Example #1
0
    def setup_contexts(cls, mechanism, sym_key, nonce_iv):
        """ Set up contexts to do wrapping/unwrapping by symmetric keys. """
        # Get a PK11 slot based on the cipher
        slot = nss.get_best_slot(mechanism)

        if sym_key is None:
            sym_key = slot.key_gen(mechanism, None,
                                   slot.get_best_key_length(mechanism))

        # If initialization vector was supplied use it, otherwise set it to
        # None
        if nonce_iv:
            iv_si = nss.SecItem(nonce_iv)
            iv_param = nss.param_from_iv(mechanism, iv_si)
        else:
            iv_data = cls.generate_nonce_iv(mechanism)
            if iv_data is not None:
                iv_si = nss.SecItem(iv_data)
                iv_param = nss.param_from_iv(mechanism, iv_si)
            else:
                iv_param = None

        # Create an encoding context
        encoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_ENCRYPT, sym_key,
                                                     iv_param)

        # Create a decoding context
        decoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_DECRYPT, sym_key,
                                                     iv_param)

        return encoding_ctx, decoding_ctx
Example #2
0
    def setup_contexts(self, mechanism, sym_key, iv):
        # Get a PK11 slot based on the cipher
        slot = nss.get_best_slot(mechanism)

        if sym_key is None:
            sym_key = slot.key_gen(
                mechanism,
                None,
                slot.get_best_key_length(mechanism))

        # If initialization vector was supplied use it, otherwise set it to
        # None
        if iv:
            iv_data = nss.read_hex(iv)
            iv_si = nss.SecItem(iv_data)
            iv_param = nss.param_from_iv(mechanism, iv_si)
        else:
            iv_length = nss.get_iv_length(mechanism)
            if iv_length > 0:
                iv_data = nss.generate_random(iv_length)
                iv_si = nss.SecItem(iv_data)
                iv_param = nss.param_from_iv(mechanism, iv_si)
            else:
                iv_param = None

        # Create an encoding context
        encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
                                                     sym_key, iv_param)

        # Create a decoding context
        decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
                                                     sym_key, iv_param)

        return encoding_ctx, decoding_ctx
Example #3
0
    def setup_contexts(cls, mechanism, sym_key, nonce_iv):
        """ Set up contexts to do wrapping/unwrapping by symmetric keys. """
        # Get a PK11 slot based on the cipher
        slot = nss.get_best_slot(mechanism)

        if sym_key is None:
            sym_key = slot.key_gen(mechanism,
                                   None,
                                   slot.get_best_key_length(mechanism))

        # If initialization vector was supplied use it, otherwise set it to
        # None
        if nonce_iv:
            iv_si = nss.SecItem(nonce_iv)
            iv_param = nss.param_from_iv(mechanism, iv_si)
        else:
            iv_data = cls.generate_nonce_iv(mechanism)
            if iv_data is not None:
                iv_si = nss.SecItem(iv_data)
                iv_param = nss.param_from_iv(mechanism, iv_si)
            else:
                iv_param = None

        # Create an encoding context
        encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
                                                     sym_key, iv_param)

        # Create a decoding context
        decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
                                                     sym_key, iv_param)

        return encoding_ctx, decoding_ctx
Example #4
0
def generate_sym_key():
    """ This Function generate Symmetric key and nonce data """    
    ## Initialize NSS Database opens temporary database and the internal PKCS #112 module
    nss.nss_init_nodb()
    ## Mechanism to be used for symmetric key 
    mechanism = nss.CKM_DES_CBC_PAD
    # From the Soft token that we initialized get slot to generate symmetric key
    slot = nss.get_best_slot(mechanism)
    # Generate a symmetric key on the pk11 slot, The sym_key is of type PK11SymKey
    sym_key = slot.key_gen(mechanism, None, slot.get_best_key_length(mechanism))

    # Generate Nonce 
    iv_length = nss.get_iv_length(mechanism)

    if iv_length > 0:
        # Generate Nonce
        iv_data = nss.generate_random(iv_length)
        # Pass this random data to NSS SecItem
        iv_si = nss.SecItem(iv_data)
        # Use the Data passed to SecItem for initialization Vector 
        iv_param = nss.param_from_iv(mechanism, iv_si)
        # Random data is converted to hex
        pki_nonce = nss.data_to_hex(data=iv_data, separator=":")
        #print "generated %d bytes initialization vector: %s" % (iv_length, pki_nonce)
    
        # Create a Symmetric key Context using the Symmetric key, nonce  The context should be 
        # used for encrypt as well as decrypt
        encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT, sym_key, iv_param)
        decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT, sym_key, iv_param)
    #return the symmetric key, nonce data, encoding context and decoding context to encrypt and 
    # decrypt
    return sym_key, pki_nonce, encoding_ctx, decoding_ctx
Example #5
0
    def setup_contexts(self, mechanism, sym_key, iv):
        # Get a PK11 slot based on the cipher
        slot = nss.get_best_slot(mechanism)

        if sym_key is None:
            sym_key = slot.key_gen(mechanism, None,
                                   slot.get_best_key_length(mechanism))

        # If initialization vector was supplied use it, otherwise set it to
        # None
        if iv:
            iv_data = nss.read_hex(iv)
            iv_si = nss.SecItem(iv_data)
            iv_param = nss.param_from_iv(mechanism, iv_si)
        else:
            iv_length = nss.get_iv_length(mechanism)
            if iv_length > 0:
                iv_data = nss.generate_random(iv_length)
                iv_si = nss.SecItem(iv_data)
                iv_param = nss.param_from_iv(mechanism, iv_si)
            else:
                iv_param = None

        # Create an encoding context
        encoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_ENCRYPT, sym_key,
                                                     iv_param)

        # Create a decoding context
        decoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_DECRYPT, sym_key,
                                                     iv_param)

        return encoding_ctx, decoding_ctx
Example #6
0
def get_decryption_context(alg_id, sym_key, params_base64):

    # Build a decryption context using the same parameters used
    # when the encryption context was created.

    # Do NOT use the params returned by get_pbe_crypto_mechanism()
    # because the params often include an IV (Initialization Vector)
    # created with random data, therefore the params used in the
    # encryption context will not match the params needed for the
    # decryption context. Instead use the params used in the
    # encryption context. For interoperability reasons we exchange the
    # params as base64 encoded binary data.

    mechanism, params = alg_id.get_pbe_crypto_mechanism(sym_key)

    # Recreate the params used during encryption by initializing a
    # SecItem from base64 text data (indicated by ascii=True)
    params = nss.SecItem(params_base64, ascii=True)

    if not options.quiet:
        print(fmt_info("get_pbe_crypto_mechanism (decrypting) returned mechanism:",
                       nss.key_mechanism_type_name(mechanism)))
        print()

    # Now we have enough information to create a decrypting context

    decrypt_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
                                                sym_key, params)

    return decrypt_ctx
Example #7
0
def get_decryption_context(alg_id, sym_key, params_base64):

    # Build a decryption context using the same parameters used
    # when the encryption context was created.

    # Do NOT use the params returned by get_pbe_crypto_mechanism()
    # because the params often include an IV (Initialization Vector)
    # created with random data, therefore the params used in the
    # encryption context will not match the params needed for the
    # decryption context. Instead use the params used in the
    # encryption context. For interoperability reasons we exchange the
    # params as base64 encoded binary data.

    mechanism, params = alg_id.get_pbe_crypto_mechanism(sym_key)

    # Recreate the params used during encryption by initializing a
    # SecItem from base64 text data (indicated by ascii=True)
    params = nss.SecItem(params_base64, ascii=True)

    if not options.quiet:
        print(
            fmt_info(
                "get_pbe_crypto_mechanism (decrypting) returned mechanism:",
                nss.key_mechanism_type_name(mechanism),
            ))
        print()

    # Now we have enough information to create a decrypting context

    decrypt_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
                                                sym_key, params)

    return decrypt_ctx
Example #8
0
def verify_sym_key(archived_key, archived_iv, algorithm, plain_text):
    """ This function verifies whether archived key is usable, Actually
    verifying this is senseless, reason any random data can be used for encryption, 
    but still just for the heck of it. 
    """
    
    # Initialize NSS 
    nss.nss_init_nodb()

    # Decode the base64 string to binary
    key = base64.decodestring(archived_data)

    # Currently we are assuming the mechanism to AES
    # Will need to add other mechanisms later, but 
    # this is just an example.
    mechanism = nss.CKM_AES_CBC_PAD

    # Get the best pkcs11 slot
    slot = nss.get_best_slot(mechanism)

    # convert the binary to hex with separtor as :
    pki_key = nss.data_to_hex(data=key,separator=":")

    # create a nssSecItem object out of it.
    key_si = nss.SecItem(nss.read_hex(pki_key))

    # Import the key to the slot
    sym_key = nss.import_sym_key(slot, mechanism, nss.PK11_OriginUnwrap, nss.CKA_ENCRYPT, key_si)

    # Same for the nonce data
    iv = base64.decodestring(archived_iv)
    iv_data = nss.data_to_hex(data=iv,separator=":")
    iv_si = nss.SecItem(nss.read_hex(iv_data))
    iv_param = nss.param_from_iv(mechanism, iv_si)


    encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,sym_key, iv_param)
    decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,sym_key, iv_param)

    cipher_text = encoding_ctx.cipher_op(plain_text)
    cipher_text += encoding_ctx.digest_final()
    print cipher_text

    decoded_text = decoding_ctx.cipher_op(cipher_text)
    decoded_text += decoding_ctx.digest_final()

    print decoded_text
Example #9
0
def setup_contexts(mechanism, key, iv):
    # Get a PK11 slot based on the cipher
    slot = nss.get_best_slot(mechanism)

    # If key was supplied use it, otherwise generate one
    if key:
        if verbose:
            print("using supplied key data")
            print("key:\n%s" % (key))
        key_si = nss.SecItem(nss.read_hex(key))
        sym_key = nss.import_sym_key(slot, mechanism, nss.PK11_OriginUnwrap,
                                     nss.CKA_ENCRYPT, key_si)
    else:
        if verbose:
            print("generating key data")
        sym_key = slot.key_gen(mechanism, None,
                               slot.get_best_key_length(mechanism))

    # If initialization vector was supplied use it, otherwise set it to None
    if iv:
        if verbose:
            print("supplied iv:\n%s" % (iv))
        iv_data = nss.read_hex(iv)
        iv_si = nss.SecItem(iv_data)
        iv_param = nss.param_from_iv(mechanism, iv_si)
    else:
        iv_length = nss.get_iv_length(mechanism)
        if iv_length > 0:
            iv_data = nss.generate_random(iv_length)
            iv_si = nss.SecItem(iv_data)
            iv_param = nss.param_from_iv(mechanism, iv_si)
            if verbose:
                print("generated %d byte initialization vector: %s" %
                      (iv_length, nss.data_to_hex(iv_data, separator=":")))
        else:
            iv_param = None

    # Create an encoding context
    encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
                                                 sym_key, iv_param)

    # Create a decoding context
    decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
                                                 sym_key, iv_param)

    return encoding_ctx, decoding_ctx
Example #10
0
def setup_contexts(mechanism, key, iv):
    # Get a PK11 slot based on the cipher
    slot = nss.get_best_slot(mechanism)

    # If key was supplied use it, otherwise generate one
    if key:
        if verbose:
            print "using supplied key data"
            print "key:\n%s" % (key)
        key_si = nss.SecItem(nss.read_hex(key))
        sym_key = nss.import_sym_key(slot, mechanism, nss.PK11_OriginUnwrap,
                                     nss.CKA_ENCRYPT, key_si)
    else:
        if verbose:
            print "generating key data"
        sym_key = slot.key_gen(mechanism, None, slot.get_best_key_length(mechanism))

    # If initialization vector was supplied use it, otherwise set it to None
    if iv:
        if verbose:
            print "supplied iv:\n%s" % (iv)
        iv_data = nss.read_hex(iv)
        iv_si = nss.SecItem(iv_data)
        iv_param = nss.param_from_iv(mechanism, iv_si)
    else:
        iv_length = nss.get_iv_length(mechanism)
        if iv_length > 0:
            iv_data = nss.generate_random(iv_length)
            iv_si = nss.SecItem(iv_data)
            iv_param = nss.param_from_iv(mechanism, iv_si)
            if verbose:
                print "generated %d byte initialization vector: %s" % \
                    (iv_length, nss.data_to_hex(iv_data, separator=":"))
        else:
            iv_param = None

    # Create an encoding context
    encoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
                                                 sym_key, iv_param)

    # Create a decoding context
    decoding_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_DECRYPT,
                                                 sym_key, iv_param)

    return encoding_ctx, decoding_ctx
def generate_sym_key():
    """ This Function generate Symmetric key and nonce data """
    ## Initialize NSS Database opens temporary database and the internal PKCS #112 module
    nss.nss_init_nodb()
    ## Mechanism to be used for symmetric key
    mechanism = nss.CKM_DES_CBC_PAD
    # From the Soft token that we initialized get slot to generate symmetric key
    slot = nss.get_best_slot(mechanism)
    # Generate a symmetric key on the pk11 slot, The sym_key is of type PK11SymKey
    sym_key = slot.key_gen(mechanism, None,
                           slot.get_best_key_length(mechanism))

    # Generate Nonce
    iv_length = nss.get_iv_length(mechanism)

    if iv_length > 0:
        # Generate Nonce
        iv_data = nss.generate_random(iv_length)
        # Pass this random data to NSS SecItem
        iv_si = nss.SecItem(iv_data)
        # Use the Data passed to SecItem for initialization Vector
        iv_param = nss.param_from_iv(mechanism, iv_si)
        # Random data is converted to hex
        pki_nonce = nss.data_to_hex(data=iv_data, separator=":")
        #print "generated %d bytes initialization vector: %s" % (iv_length, pki_nonce)

        # Create a Symmetric key Context using the Symmetric key, nonce  The context should be
        # used for encrypt as well as decrypt
        encoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_ENCRYPT, sym_key,
                                                     iv_param)
        decoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_DECRYPT, sym_key,
                                                     iv_param)
    #return the symmetric key, nonce data, encoding context and decoding context to encrypt and
    # decrypt
    return sym_key, pki_nonce, encoding_ctx, decoding_ctx
Example #12
0
def get_encryption_context(alg_id, sym_key):

    # In order for NSS to encrypt and decrypt data it needs an
    # encryption context to perform the operation in. The cipher used
    # for the encryption context is specified with a PK11 mechanism.
    # The cipher likely also needs additional parameters (i.e. an
    # Initialization Vector (IV) and possibly other values.
    # The get_pbe_crypto_mechanism() call computes the mechanism
    # and parameters for the PBE symmetric key we're using.
    #
    # Because the decryption context needs the same params used in
    # the encryption context we save the param block returned by
    # get_pbe_crypto_mechanism(). So that it can be passed to
    # create_context_by_sym_key() when creating the decryption context.
    # It's often the case the decryption is performed by a separate
    # process so in this example we illustrate exchanging the param
    # as base64 data.

    mechanism, params = alg_id.get_pbe_crypto_mechanism(sym_key)

    # Format the params binary data into a base64 string.  The zero
    # passed for the chars_per_line parameter indicates we want the
    # base64 data as one single string as opposed to a list of wrapped
    # strings.
    params_base64 = params.to_base64(0)

    if not options.quiet:
        print(
            fmt_info(
                "get_pbe_crypto_mechanism (encrypting) returned mechanism:",
                nss.key_mechanism_type_name(mechanism),
            ))
        print(
            fmt_info("get_pbe_crypto_mechanism (encrypting) returned params:",
                     params))
        print()

    # Now we have enough information to create an encrypting context
    # and decrypting the data.

    encrypt_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
                                                sym_key, params)

    # Return the encrypting context and it's parameter block so that the
    # decryption context can use the same parameter block.
    return encrypt_ctx, params_base64
Example #13
0
    def __call__(self, element, mac=None):
        (mech, ivlen) = fetch(element, "./xenc:EncryptionMethod/@Algorithm", convertAlgorithm)
        data = fetch(element, "./xenc:CipherData/xenc:CipherValue/text()", base64.b64decode)

        # If a MAC is present, perform validation.
        if mac:
            tmp = self.__hmac.copy()
            tmp.update(data)
            if tmp.digest() != mac:
                raise ValidationError("MAC validation failed!")

        # Decrypt the data.
        slot = nss.get_best_slot(mech)
        key = nss.import_sym_key(slot, mech, nss.PK11_OriginUnwrap, nss.CKA_ENCRYPT, self.__key)
        iv = nss.param_from_iv(mech, nss.SecItem(data[0:ivlen//8]))
        ctx = nss.create_context_by_sym_key(mech, nss.CKA_DECRYPT, key, iv)
        out = ctx.cipher_op(data[ivlen // 8:])
        out += ctx.digest_final()
        return out
Example #14
0
    def __call__(self, element, mac=None):
        (mech, ivlen) = fetch(element, "./xenc:EncryptionMethod/@Algorithm", convertAlgorithm)
        data = fetch(element, "./xenc:CipherData/xenc:CipherValue/text()", base64.b64decode)

        # If a MAC is present, perform validation.
        if mac:
            tmp = self.__hmac.copy()
            tmp.update(data)
            if tmp.digest() != mac:
                raise ValidationError("MAC validation failed!")

        # Decrypt the data.
        slot = nss.get_best_slot(mech)
        key = nss.import_sym_key(slot, mech, nss.PK11_OriginUnwrap, nss.CKA_ENCRYPT, self.__key)
        iv = nss.param_from_iv(mech, nss.SecItem(data[0:ivlen/8]))
        ctx = nss.create_context_by_sym_key(mech, nss.CKA_DECRYPT, key, iv)
        out = ctx.cipher_op(data[ivlen / 8:])
        out += ctx.digest_final()
        return out
Example #15
0
def get_encryption_context(alg_id, sym_key):

    # In order for NSS to encrypt and decrypt data it needs an
    # encryption context to perform the operation in. The cipher used
    # for the encryption context is specified with a PK11 mechanism.
    # The cipher likely also needs additional parameters (i.e. an
    # Initialization Vector (IV) and possibly other values.
    # The get_pbe_crypto_mechanism() call computes the mechanism
    # and parameters for the PBE symmetric key we're using.
    #
    # Because the decryption context needs the same params used in
    # the encryption context we save the param block returned by
    # get_pbe_crypto_mechanism(). So that it can be passed to
    # create_context_by_sym_key() when creating the decryption context.
    # It's often the case the decryption is performed by a separate
    # process so in this example we illustrate exchanging the param
    # as base64 data.

    mechanism, params = alg_id.get_pbe_crypto_mechanism(sym_key)

    # Format the params binary data into a base64 string.  The zero
    # passed for the chars_per_line parameter indicates we want the
    # base64 data as one single string as opposed to a list of wrapped
    # strings.
    params_base64 = params.to_base64(0)

    if not options.quiet:
        print(fmt_info("get_pbe_crypto_mechanism (encrypting) returned mechanism:",
                       nss.key_mechanism_type_name(mechanism)))
        print(fmt_info("get_pbe_crypto_mechanism (encrypting) returned params:",
                       params))
        print()

    # Now we have enough information to create an encrypting context
    # and decrypting the data.

    encrypt_ctx = nss.create_context_by_sym_key(mechanism, nss.CKA_ENCRYPT,
                                                sym_key, params)

    # Return the encrypting context and it's parameter block so that the
    # decryption context can use the same parameter block.
    return encrypt_ctx, params_base64
Example #16
0
    def forward(self, *args, **options):
        data = options.get('data')
        input_file = options.get('in')

        password = options.get('password')
        password_file = options.get('password_file')

        override_password = options.pop('override_password', False)

        # don't send these parameters to server
        if 'data' in options:
            del options['data']
        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 and input_file:
            raise errors.MutuallyExclusiveError(
                reason=_('Input data specified multiple times'))

        elif data:
            if len(data) > MAX_VAULT_DATA_SIZE:
                raise errors.ValidationError(name="data", error=_(
                    "Size of data exceeds the limit. Current vault data size "
                    "limit is %(limit)d B")
                    % {'limit': MAX_VAULT_DATA_SIZE})

        elif input_file:
            try:
                stat = os.stat(input_file)
            except OSError as exc:
                raise errors.ValidationError(name="in", error=_(
                    "Cannot read file '%(filename)s': %(exc)s")
                    % {'filename': input_file, 'exc': exc.args[1]})
            if stat.st_size > MAX_VAULT_DATA_SIZE:
                raise errors.ValidationError(name="in", error=_(
                    "Size of data exceeds the limit. Current vault data size "
                    "limit is %(limit)d B")
                    % {'limit': MAX_VAULT_DATA_SIZE})
            data = validated_read('in', input_file, mode='rb')

        else:
            data = ''

        if self.api.env.in_server:
            backend = self.api.Backend.ldap2
        else:
            backend = self.api.Backend.rpcclient
        if not backend.isconnected():
            backend.connect()

        # retrieve vault info
        vault = self.api.Command.vault_show(*args, **options)['result']

        vault_type = vault['ipavaulttype'][0]

        if vault_type == u'standard':

            encrypted_key = None

        elif vault_type == u'symmetric':

            # get password
            if password and password_file:
                raise errors.MutuallyExclusiveError(
                    reason=_('Password specified multiple times'))

            elif password:
                pass

            elif password_file:
                password = validated_read('password-file',
                                          password_file,
                                          encoding='utf-8')
                password = password.rstrip('\n')

            else:
                if override_password:
                    password = get_new_password()
                else:
                    password = get_existing_password()

            if not override_password:
                # verify password by retrieving existing data
                opts = options.copy()
                opts['password'] = password
                try:
                    self.api.Command.vault_retrieve(*args, **opts)
                except errors.NotFound:
                    pass

            salt = vault['ipavaultsalt'][0]

            # generate encryption key from vault password
            encryption_key = generate_symmetric_key(password, salt)

            # encrypt data with encryption key
            data = encrypt(data, symmetric_key=encryption_key)

            encrypted_key = None

        elif vault_type == u'asymmetric':

            public_key = vault['ipavaultpublickey'][0].encode('utf-8')

            # generate encryption key
            encryption_key = base64.b64encode(os.urandom(32))

            # encrypt data with encryption key
            data = encrypt(data, symmetric_key=encryption_key)

            # encrypt encryption key with public key
            encrypted_key = encrypt(encryption_key, public_key=public_key)

        else:
            raise errors.ValidationError(
                name='vault_type',
                error=_('Invalid vault type'))

        # initialize NSS database
        nss.nss_init(api.env.nss_dir)

        # retrieve transport certificate
        config = self.api.Command.vaultconfig_show()['result']
        transport_cert_der = config['transport_cert']
        nss_transport_cert = nss.Certificate(transport_cert_der)

        # generate session key
        mechanism = nss.CKM_DES3_CBC_PAD
        slot = nss.get_best_slot(mechanism)
        key_length = slot.get_best_key_length(mechanism)
        session_key = slot.key_gen(mechanism, None, key_length)

        # wrap session key with transport certificate
        # pylint: disable=no-member
        public_key = nss_transport_cert.subject_public_key_info.public_key
        # pylint: enable=no-member
        wrapped_session_key = nss.pub_wrap_sym_key(mechanism,
                                                   public_key,
                                                   session_key)

        options['session_key'] = wrapped_session_key.data

        nonce_length = nss.get_iv_length(mechanism)
        nonce = nss.generate_random(nonce_length)
        options['nonce'] = nonce

        vault_data = {}
        vault_data[u'data'] = base64.b64encode(data).decode('utf-8')

        if encrypted_key:
            vault_data[u'encrypted_key'] = base64.b64encode(encrypted_key)\
                .decode('utf-8')

        json_vault_data = json.dumps(vault_data)

        # wrap vault_data with session key
        iv_si = nss.SecItem(nonce)
        iv_param = nss.param_from_iv(mechanism, iv_si)

        encoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_ENCRYPT,
                                                     session_key,
                                                     iv_param)

        wrapped_vault_data = encoding_ctx.cipher_op(json_vault_data)\
            + encoding_ctx.digest_final()

        options['vault_data'] = wrapped_vault_data

        return self.api.Command.vault_archive_internal(*args, **options)
Example #17
0
    def forward(self, *args, **options):

        name = args[-1]

        data = options.get('data')
        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:
            del options['data']
        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 and input_file:
            raise errors.MutuallyExclusiveError(
                reason=_('Input data specified multiple times'))

        elif input_file:
            data = validated_read('in', input_file, mode='rb')

        elif not data:
            data = ''

        if self.api.env.in_server:
            backend = self.api.Backend.ldap2
        else:
            backend = self.api.Backend.rpcclient
        if not backend.isconnected():
            backend.connect(ccache=krbV.default_context().default_ccache())

        # retrieve vault info
        vault = self.api.Command.vault_show(*args, **options)['result']

        vault_type = vault['ipavaulttype'][0]

        if vault_type == u'standard':

            encrypted_key = None

        elif vault_type == u'symmetric':

            # get password
            if password and password_file:
                raise errors.MutuallyExclusiveError(
                    reason=_('Password specified multiple times'))

            elif password:
                pass

            elif password_file:
                password = validated_read('password-file',
                                          password_file,
                                          encoding='utf-8')
                password = password.rstrip('\n')

            else:
                password = self.obj.get_existing_password()

            # verify password by retrieving existing data
            opts = options.copy()
            opts['password'] = password
            try:
                self.api.Command.vault_retrieve(*args, **opts)
            except errors.NotFound:
                pass

            salt = vault['ipavaultsalt'][0]

            # generate encryption key from vault password
            encryption_key = self.obj.generate_symmetric_key(
                password, salt)

            # encrypt data with encryption key
            data = self.obj.encrypt(data, symmetric_key=encryption_key)

            encrypted_key = None

        elif vault_type == u'asymmetric':

            public_key = vault['ipavaultpublickey'][0].encode('utf-8')

            # generate encryption key
            encryption_key = base64.b64encode(os.urandom(32))

            # encrypt data with encryption key
            data = self.obj.encrypt(data, symmetric_key=encryption_key)

            # encrypt encryption key with public key
            encrypted_key = self.obj.encrypt(
                encryption_key, public_key=public_key)

        else:
            raise errors.ValidationError(
                name='vault_type',
                error=_('Invalid vault type'))

        # initialize NSS database
        current_dbdir = paths.IPA_NSSDB_DIR
        nss.nss_init(current_dbdir)

        # retrieve transport certificate
        config = self.api.Command.vaultconfig_show()['result']
        transport_cert_der = config['transport_cert']
        nss_transport_cert = nss.Certificate(transport_cert_der)

        # generate session key
        mechanism = nss.CKM_DES3_CBC_PAD
        slot = nss.get_best_slot(mechanism)
        key_length = slot.get_best_key_length(mechanism)
        session_key = slot.key_gen(mechanism, None, key_length)

        # wrap session key with transport certificate
        public_key = nss_transport_cert.subject_public_key_info.public_key
        wrapped_session_key = nss.pub_wrap_sym_key(mechanism,
                                                   public_key,
                                                   session_key)

        options['session_key'] = wrapped_session_key.data

        nonce_length = nss.get_iv_length(mechanism)
        nonce = nss.generate_random(nonce_length)
        options['nonce'] = nonce

        vault_data = {}
        vault_data[u'data'] = base64.b64encode(data).decode('utf-8')

        if encrypted_key:
            vault_data[u'encrypted_key'] = base64.b64encode(encrypted_key)\
                .decode('utf-8')

        json_vault_data = json.dumps(vault_data)

        # wrap vault_data with session key
        iv_si = nss.SecItem(nonce)
        iv_param = nss.param_from_iv(mechanism, iv_si)

        encoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_ENCRYPT,
                                                     session_key,
                                                     iv_param)

        wrapped_vault_data = encoding_ctx.cipher_op(json_vault_data)\
            + encoding_ctx.digest_final()

        options['vault_data'] = wrapped_vault_data

        return self.api.Command.vault_archive_internal(*args, **options)
Example #18
0
    def forward(self, *args, **options):

        name = args[-1]

        output_file = options.get('out')

        password = options.get('password')
        password_file = options.get('password_file')
        private_key = options.get('private_key')
        private_key_file = options.get('private_key_file')

        # don't send these parameters to server
        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' in options:
            del options['private_key']
        if 'private_key_file' in options:
            del options['private_key_file']

        if self.api.env.in_server:
            backend = self.api.Backend.ldap2
        else:
            backend = self.api.Backend.rpcclient
        if not backend.isconnected():
            backend.connect(ccache=krbV.default_context().default_ccache())

        # retrieve vault info
        vault = self.api.Command.vault_show(*args, **options)['result']

        vault_type = vault['ipavaulttype'][0]

        # initialize NSS database
        current_dbdir = paths.IPA_NSSDB_DIR
        nss.nss_init(current_dbdir)

        # retrieve transport certificate
        config = self.api.Command.vaultconfig_show()['result']
        transport_cert_der = config['transport_cert']
        nss_transport_cert = nss.Certificate(transport_cert_der)

        # generate session key
        mechanism = nss.CKM_DES3_CBC_PAD
        slot = nss.get_best_slot(mechanism)
        key_length = slot.get_best_key_length(mechanism)
        session_key = slot.key_gen(mechanism, None, key_length)

        # wrap session key with transport certificate
        public_key = nss_transport_cert.subject_public_key_info.public_key
        wrapped_session_key = nss.pub_wrap_sym_key(mechanism,
                                                   public_key,
                                                   session_key)

        # send retrieval request to server
        options['session_key'] = wrapped_session_key.data

        response = self.api.Command.vault_retrieve_internal(*args, **options)

        result = response['result']
        nonce = result['nonce']

        # unwrap data with session key
        wrapped_vault_data = result['vault_data']

        iv_si = nss.SecItem(nonce)
        iv_param = nss.param_from_iv(mechanism, iv_si)

        decoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_DECRYPT,
                                                     session_key,
                                                     iv_param)

        json_vault_data = decoding_ctx.cipher_op(wrapped_vault_data)\
            + decoding_ctx.digest_final()

        vault_data = json.loads(json_vault_data)
        data = base64.b64decode(vault_data[u'data'].encode('utf-8'))

        encrypted_key = None

        if 'encrypted_key' in vault_data:
            encrypted_key = base64.b64decode(vault_data[u'encrypted_key']
                                             .encode('utf-8'))

        if vault_type == u'standard':

            pass

        elif vault_type == u'symmetric':

            salt = vault['ipavaultsalt'][0]

            # get encryption key from vault password
            if password and password_file:
                raise errors.MutuallyExclusiveError(
                    reason=_('Password specified multiple times'))

            elif password:
                pass

            elif password_file:
                password = validated_read('password-file',
                                          password_file,
                                          encoding='utf-8')
                password = password.rstrip('\n')

            else:
                password = self.obj.get_existing_password()

            # generate encryption key from password
            encryption_key = self.obj.generate_symmetric_key(password, salt)

            # decrypt data with encryption key
            data = self.obj.decrypt(data, symmetric_key=encryption_key)

        elif vault_type == u'asymmetric':

            # get encryption key with vault private key
            if private_key and private_key_file:
                raise errors.MutuallyExclusiveError(
                    reason=_('Private key specified multiple times'))

            elif private_key:
                pass

            elif private_key_file:
                private_key = validated_read('private-key-file',
                                             private_key_file,
                                             mode='rb')

            else:
                raise errors.ValidationError(
                    name='private_key',
                    error=_('Missing vault private key'))

            # decrypt encryption key with private key
            encryption_key = self.obj.decrypt(
                encrypted_key, private_key=private_key)

            # decrypt data with encryption key
            data = self.obj.decrypt(data, symmetric_key=encryption_key)

        else:
            raise errors.ValidationError(
                name='vault_type',
                error=_('Invalid vault type'))

        if output_file:
            with open(output_file, 'w') as f:
                f.write(data)

        else:
            response['result'] = {'data': data}

        return response
Example #19
0
    def forward(self, *args, **options):
        output_file = options.get('out')

        password = options.get('password')
        password_file = options.get('password_file')
        private_key = options.get('private_key')
        private_key_file = options.get('private_key_file')

        # don't send these parameters to server
        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' in options:
            del options['private_key']
        if 'private_key_file' in options:
            del options['private_key_file']

        if self.api.env.in_server:
            backend = self.api.Backend.ldap2
        else:
            backend = self.api.Backend.rpcclient
        if not backend.isconnected():
            backend.connect()

        # retrieve vault info
        vault = self.api.Command.vault_show(*args, **options)['result']

        vault_type = vault['ipavaulttype'][0]

        # initialize NSS database
        nss.nss_init(api.env.nss_dir)

        # retrieve transport certificate
        config = self.api.Command.vaultconfig_show()['result']
        transport_cert_der = config['transport_cert']
        nss_transport_cert = nss.Certificate(transport_cert_der)

        # generate session key
        mechanism = nss.CKM_DES3_CBC_PAD
        slot = nss.get_best_slot(mechanism)
        key_length = slot.get_best_key_length(mechanism)
        session_key = slot.key_gen(mechanism, None, key_length)

        # wrap session key with transport certificate
        # pylint: disable=no-member
        public_key = nss_transport_cert.subject_public_key_info.public_key
        # pylint: enable=no-member
        wrapped_session_key = nss.pub_wrap_sym_key(mechanism,
                                                   public_key,
                                                   session_key)

        # send retrieval request to server
        options['session_key'] = wrapped_session_key.data

        response = self.api.Command.vault_retrieve_internal(*args, **options)

        result = response['result']
        nonce = result['nonce']

        # unwrap data with session key
        wrapped_vault_data = result['vault_data']

        iv_si = nss.SecItem(nonce)
        iv_param = nss.param_from_iv(mechanism, iv_si)

        decoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_DECRYPT,
                                                     session_key,
                                                     iv_param)

        json_vault_data = decoding_ctx.cipher_op(wrapped_vault_data)\
            + decoding_ctx.digest_final()

        vault_data = json.loads(json_vault_data.decode('utf-8'))
        data = base64.b64decode(vault_data[u'data'].encode('utf-8'))

        encrypted_key = None

        if 'encrypted_key' in vault_data:
            encrypted_key = base64.b64decode(vault_data[u'encrypted_key']
                                             .encode('utf-8'))

        if vault_type == u'standard':

            pass

        elif vault_type == u'symmetric':

            salt = vault['ipavaultsalt'][0]

            # get encryption key from vault password
            if password and password_file:
                raise errors.MutuallyExclusiveError(
                    reason=_('Password specified multiple times'))

            elif password:
                pass

            elif password_file:
                password = validated_read('password-file',
                                          password_file,
                                          encoding='utf-8')
                password = password.rstrip('\n')

            else:
                password = get_existing_password()

            # generate encryption key from password
            encryption_key = generate_symmetric_key(password, salt)

            # decrypt data with encryption key
            data = decrypt(data, symmetric_key=encryption_key)

        elif vault_type == u'asymmetric':

            # get encryption key with vault private key
            if private_key and private_key_file:
                raise errors.MutuallyExclusiveError(
                    reason=_('Private key specified multiple times'))

            elif private_key:
                pass

            elif private_key_file:
                private_key = validated_read('private-key-file',
                                             private_key_file,
                                             mode='rb')

            else:
                raise errors.ValidationError(
                    name='private_key',
                    error=_('Missing vault private key'))

            # decrypt encryption key with private key
            encryption_key = decrypt(encrypted_key, private_key=private_key)

            # decrypt data with encryption key
            data = decrypt(data, symmetric_key=encryption_key)

        else:
            raise errors.ValidationError(
                name='vault_type',
                error=_('Invalid vault type'))

        if output_file:
            with open(output_file, 'w') as f:
                f.write(data)

        else:
            response['result'] = {'data': data}

        return response
Example #20
0
    def forward(self, *args, **options):
        data = options.get('data')
        input_file = options.get('in')

        password = options.get('password')
        password_file = options.get('password_file')

        override_password = options.pop('override_password', False)

        # don't send these parameters to server
        if 'data' in options:
            del options['data']
        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 and input_file:
            raise errors.MutuallyExclusiveError(
                reason=_('Input data specified multiple times'))

        elif data:
            if len(data) > MAX_VAULT_DATA_SIZE:
                raise errors.ValidationError(name="data", error=_(
                    "Size of data exceeds the limit. Current vault data size "
                    "limit is %(limit)d B")
                    % {'limit': MAX_VAULT_DATA_SIZE})

        elif input_file:
            try:
                stat = os.stat(input_file)
            except OSError as exc:
                raise errors.ValidationError(name="in", error=_(
                    "Cannot read file '%(filename)s': %(exc)s")
                    % {'filename': input_file, 'exc': exc.args[1]})
            if stat.st_size > MAX_VAULT_DATA_SIZE:
                raise errors.ValidationError(name="in", error=_(
                    "Size of data exceeds the limit. Current vault data size "
                    "limit is %(limit)d B")
                    % {'limit': MAX_VAULT_DATA_SIZE})
            data = validated_read('in', input_file, mode='rb')

        else:
            data = ''

        if self.api.env.in_server:
            backend = self.api.Backend.ldap2
        else:
            backend = self.api.Backend.rpcclient
        if not backend.isconnected():
            backend.connect()

        # retrieve vault info
        vault = self.api.Command.vault_show(*args, **options)['result']

        vault_type = vault['ipavaulttype'][0]

        if vault_type == u'standard':

            encrypted_key = None

        elif vault_type == u'symmetric':

            # get password
            if password and password_file:
                raise errors.MutuallyExclusiveError(
                    reason=_('Password specified multiple times'))

            elif password:
                pass

            elif password_file:
                password = validated_read('password-file',
                                          password_file,
                                          encoding='utf-8')
                password = password.rstrip('\n')

            else:
                if override_password:
                    password = get_new_password()
                else:
                    password = get_existing_password()

            if not override_password:
                # verify password by retrieving existing data
                opts = options.copy()
                opts['password'] = password
                try:
                    self.api.Command.vault_retrieve(*args, **opts)
                except errors.NotFound:
                    pass

            salt = vault['ipavaultsalt'][0]

            # generate encryption key from vault password
            encryption_key = generate_symmetric_key(password, salt)

            # encrypt data with encryption key
            data = encrypt(data, symmetric_key=encryption_key)

            encrypted_key = None

        elif vault_type == u'asymmetric':

            public_key = vault['ipavaultpublickey'][0].encode('utf-8')

            # generate encryption key
            encryption_key = base64.b64encode(os.urandom(32))

            # encrypt data with encryption key
            data = encrypt(data, symmetric_key=encryption_key)

            # encrypt encryption key with public key
            encrypted_key = encrypt(encryption_key, public_key=public_key)

        else:
            raise errors.ValidationError(
                name='vault_type',
                error=_('Invalid vault type'))

        # initialize NSS database
        nss.nss_init(api.env.nss_dir)

        # retrieve transport certificate
        config = self.api.Command.vaultconfig_show()['result']
        transport_cert_der = config['transport_cert']
        nss_transport_cert = nss.Certificate(transport_cert_der)

        # generate session key
        mechanism = nss.CKM_DES3_CBC_PAD
        slot = nss.get_best_slot(mechanism)
        key_length = slot.get_best_key_length(mechanism)
        session_key = slot.key_gen(mechanism, None, key_length)

        # wrap session key with transport certificate
        # pylint: disable=no-member
        public_key = nss_transport_cert.subject_public_key_info.public_key
        # pylint: enable=no-member
        wrapped_session_key = nss.pub_wrap_sym_key(mechanism,
                                                   public_key,
                                                   session_key)

        options['session_key'] = wrapped_session_key.data

        nonce_length = nss.get_iv_length(mechanism)
        nonce = nss.generate_random(nonce_length)
        options['nonce'] = nonce

        vault_data = {}
        vault_data[u'data'] = base64.b64encode(data).decode('utf-8')

        if encrypted_key:
            vault_data[u'encrypted_key'] = base64.b64encode(encrypted_key)\
                .decode('utf-8')

        json_vault_data = json.dumps(vault_data)

        # wrap vault_data with session key
        iv_si = nss.SecItem(nonce)
        iv_param = nss.param_from_iv(mechanism, iv_si)

        encoding_ctx = nss.create_context_by_sym_key(mechanism,
                                                     nss.CKA_ENCRYPT,
                                                     session_key,
                                                     iv_param)

        wrapped_vault_data = encoding_ctx.cipher_op(json_vault_data)\
            + encoding_ctx.digest_final()

        options['vault_data'] = wrapped_vault_data

        return self.api.Command.vault_archive_internal(*args, **options)