예제 #1
0
파일: decrypter.py 프로젝트: mahak/swift
    def decrypt_value_with_meta(self, value, key, required, decoder):
        """
        Base64-decode and decrypt a value if crypto meta can be extracted from
        the value itself, otherwise return the value unmodified.

        A value should either be a string that does not contain the ';'
        character or should be of the form:

            <base64-encoded ciphertext>;swift_meta=<crypto meta>

        :param value: value to decrypt
        :param key: crypto key to use
        :param required: if True then the value is required to be decrypted
                         and an EncryptionException will be raised if the
                         header cannot be decrypted due to missing crypto meta.
        :param decoder: function to turn the decrypted bytes into useful data
        :returns: decrypted value if crypto meta is found, otherwise the
                  unmodified value
        :raises EncryptionException: if an error occurs while parsing crypto
                                     meta or if the header value was required
                                     to be decrypted but crypto meta was not
                                     found.
        """
        extracted_value, crypto_meta = extract_crypto_meta(value)
        if crypto_meta:
            self.crypto.check_crypto_meta(crypto_meta)
            value = self.decrypt_value(
                extracted_value, key, crypto_meta, decoder)
        elif required:
            raise EncryptionException(
                "Missing crypto meta in value %s" % value)

        return value
예제 #2
0
파일: decrypter.py 프로젝트: mahak/swift
 def decrypt_obj_dict(self, req, obj_dict):
     if 'hash' in obj_dict:
         # each object's etag may have been encrypted with a different key
         # so fetch keys based on its crypto meta
         ciphertext, crypto_meta = extract_crypto_meta(obj_dict['hash'])
         bad_keys = set()
         if crypto_meta:
             try:
                 self.crypto.check_crypto_meta(crypto_meta)
                 keys = self.get_decryption_keys(req, crypto_meta)
                 # Note that symlinks (for example) may put swift paths in
                 # the listing ETag, so we can't just use ASCII.
                 obj_dict['hash'] = self.decrypt_value(
                     ciphertext, keys['container'], crypto_meta,
                     decoder=lambda x: x.decode('utf-8'))
             except EncryptionException as err:
                 if not isinstance(err, UnknownSecretIdError) or \
                         err.args[0] not in bad_keys:
                     # Only warn about an unknown key once per listing
                     self.logger.error(
                         "Error decrypting container listing: %s",
                         err)
                 if isinstance(err, UnknownSecretIdError):
                     bad_keys.add(err.args[0])
                 obj_dict['hash'] = '<unknown>'
     return obj_dict
예제 #3
0
 def decrypt_obj_dict(self, req, obj_dict):
     if 'hash' in obj_dict:
         # each object's etag may have been encrypted with a different key
         # so fetch keys based on its crypto meta
         ciphertext, crypto_meta = extract_crypto_meta(obj_dict['hash'])
         bad_keys = set()
         if crypto_meta:
             try:
                 self.crypto.check_crypto_meta(crypto_meta)
                 keys = self.get_decryption_keys(req, crypto_meta)
                 # Note that symlinks (for example) may put swift paths in
                 # the listing ETag, so we can't just use ASCII.
                 obj_dict['hash'] = self.decrypt_value(
                     ciphertext,
                     keys['container'],
                     crypto_meta,
                     decoder=lambda x: x.decode('utf-8'))
             except EncryptionException as err:
                 if not isinstance(err, UnknownSecretIdError) or \
                         err.args[0] not in bad_keys:
                     # Only warn about an unknown key once per listing
                     self.logger.error(
                         "Error decrypting container listing: %s", err)
                 if isinstance(err, UnknownSecretIdError):
                     bad_keys.add(err.args[0])
                 obj_dict['hash'] = '<unknown>'
     return obj_dict
    def test_extract_crypto_meta(self):
        val, meta = crypto_utils.extract_crypto_meta(
            'abc; swift_meta=%s' % self.serialized_meta)
        self.assertEqual('abc', val)
        self.assertDictEqual(self.meta, meta)

        val, meta = crypto_utils.extract_crypto_meta(
            'abc; swift_meta=%s' % self.serialized_meta_with_key)
        self.assertEqual('abc', val)
        self.assertDictEqual(self.meta_with_key, meta)

        val, meta = crypto_utils.extract_crypto_meta('abc')
        self.assertEqual('abc', val)
        self.assertIsNone(meta)

        # other param names will be ignored
        val, meta = crypto_utils.extract_crypto_meta('abc; foo=bar')
        self.assertEqual('abc', val)
        self.assertIsNone(meta)
예제 #5
0
    def test_extract_crypto_meta(self):
        val, meta = crypto_utils.extract_crypto_meta('abc; swift_meta=%s' %
                                                     self.serialized_meta)
        self.assertEqual('abc', val)
        self.assertDictEqual(self.meta, meta)

        val, meta = crypto_utils.extract_crypto_meta(
            'abc; swift_meta=%s' % self.serialized_meta_with_key)
        self.assertEqual('abc', val)
        self.assertDictEqual(self.meta_with_key, meta)

        val, meta = crypto_utils.extract_crypto_meta('abc')
        self.assertEqual('abc', val)
        self.assertIsNone(meta)

        # other param names will be ignored
        val, meta = crypto_utils.extract_crypto_meta('abc; foo=bar')
        self.assertEqual('abc', val)
        self.assertIsNone(meta)

        val, meta = crypto_utils.extract_crypto_meta(
            'abc; swift_meta=%s; foo=bar' % self.serialized_meta_with_key)
        self.assertEqual('abc', val)
        self.assertDictEqual(self.meta_with_key, meta)
예제 #6
0
 def decrypt_obj_dict(self, req, obj_dict):
     if 'hash' in obj_dict:
         # each object's etag may have been encrypted with a different key
         # so fetch keys based on its crypto meta
         ciphertext, crypto_meta = extract_crypto_meta(obj_dict['hash'])
         bad_keys = set()
         if crypto_meta:
             try:
                 self.crypto.check_crypto_meta(crypto_meta)
                 keys = self.get_decryption_keys(req, crypto_meta)
                 obj_dict['hash'] = self.decrypt_value(
                     ciphertext, keys['container'], crypto_meta)
             except EncryptionException as err:
                 if not isinstance(err, UnknownSecretIdError) or \
                         err.args[0] not in bad_keys:
                     # Only warn about an unknown key once per listing
                     self.logger.error(
                         "Error decrypting container listing: %s",
                         err)
                 if isinstance(err, UnknownSecretIdError):
                     bad_keys.add(err.args[0])
                 obj_dict['hash'] = '<unknown>'
     return obj_dict
예제 #7
0
 def test_append_then_extract_crypto_meta(self):
     val = 'abc'
     actual = crypto_utils.extract_crypto_meta(
         crypto_utils.append_crypto_meta(val, self.meta))
     self.assertEqual((val, self.meta), actual)
예제 #8
0
 def test_append_then_extract_crypto_meta(self):
     val = 'abc'
     actual = crypto_utils.extract_crypto_meta(
         crypto_utils.append_crypto_meta(val, self.meta))
     self.assertEqual((val, self.meta), actual)