def request(self,
                method,
                url,
                query_params=None,
                headers=None,
                post_params=None,
                body=None,
                _preload_content=True,
                _request_timeout=None):
        check = -1

        if body:
            if url == "testservice/headers":
                iv = headers["x-iv"]
                encrypted_key = headers["x-key"]
                oaep_digest_algo = headers[
                    "x-oaep-digest"] if "x-oaep-digest" in headers else None

                params = SessionKeyParams(self._config, encrypted_key, iv,
                                          oaep_digest_algo)
            else:
                params = None

            plain = encryption.decrypt_payload(body, self._config, params)
            check = plain["data"]["secret2"] - plain["data"]["secret1"]
            res = {"data": {"secret": check}}
        else:
            res = {"data": {"secret": [53, 84, 75]}}

        if url == "testservice/headers" and method in ["GET", "POST", "PUT"]:
            params = SessionKeyParams.generate(self._config)
            json_resp = encryption.encrypt_payload(res, self._config, params)

            response_headers = {
                "Content-Type": "application/json",
                "x-iv": params.iv_value,
                "x-key": params.encrypted_key_value,
                "x-oaep-digest": self._config.oaep_padding_digest_algorithm
            }
            mock_headers = Mock(return_value=response_headers)
        else:
            json_resp = encryption.encrypt_payload(res, self._config)
            mock_headers = Mock(
                return_value={"Content-Type": "application/json"})

        response = Mock()
        response.status = 200
        response.getheaders = mock_headers

        if method in ["GET", "POST", "PUT"]:
            response.data = json_resp
        else:
            response.data = "OK" if check == 0 else "KO"

        return response
    def _decrypt_payload(self, headers, body):
        """Encryption enforcement based on configuration - decrypt using session key params from header or body"""

        conf = self._encryption_conf
        params = None

        if conf.use_http_headers:
            if conf.iv_field_name in headers and conf.encrypted_key_field_name in headers:
                iv = headers.pop(conf.iv_field_name)
                encrypted_key = headers.pop(conf.encrypted_key_field_name)
                oaep_digest_algo = headers.pop(conf.oaep_padding_digest_algorithm_field_name) \
                    if _contains_param(conf.oaep_padding_digest_algorithm_field_name, headers) else None
                if _contains_param(conf.encryption_certificate_fingerprint_field_name, headers):
                    del headers[conf.encryption_certificate_fingerprint_field_name]
                if _contains_param(conf.encryption_key_fingerprint_field_name, headers):
                    del headers[conf.encryption_key_fingerprint_field_name]

                params = SessionKeyParams(conf, encrypted_key, iv, oaep_digest_algo)
            else:
                # skip decryption and return original body if not iv nor key is in headers
                return body

        decrypted_body = decrypt_payload(body, conf, params)
        payload = json.dumps(decrypted_body).encode('utf-8')

        return payload
    def _encrypt_payload(self, headers, body):
        """Encryption enforcement based on configuration - encrypt and add session key params to header or body"""

        conf = self._encryption_conf

        if conf.use_http_headers:
            params = SessionKeyParams.generate(conf)

            encryption_params = {
                conf.iv_field_name: params.iv_value,
                conf.encrypted_key_field_name: params.encrypted_key_value
            }
            if conf.encryption_certificate_fingerprint_field_name:
                encryption_params[conf.encryption_certificate_fingerprint_field_name] = \
                    conf.encryption_certificate_fingerprint
            if conf.encryption_key_fingerprint_field_name:
                encryption_params[conf.encryption_key_fingerprint_field_name] = conf.encryption_key_fingerprint
            if conf.oaep_padding_digest_algorithm_field_name:
                encryption_params[conf.oaep_padding_digest_algorithm_field_name] = conf.oaep_padding_digest_algorithm

            encrypted_payload = encrypt_payload(body, conf, params)
            headers.update(encryption_params)
        else:
            encrypted_payload = encrypt_payload(body, conf)

        return encrypted_payload
def decrypt_payload(payload, config, _params=None):
    """Decrypt some fields of a JSON payload using the given configuration."""

    try:
        json_payload = payload if type(payload) is dict else json.loads(
            payload)

        for elem, target in config.paths["$"].to_decrypt.items():
            try:
                node = get_node(json_payload, elem)

                cipher_text = decode_value(
                    node.pop(config.encrypted_value_field_name),
                    config.data_encoding)

                if not _params:
                    try:
                        encrypted_key = node.pop(
                            config.encrypted_key_field_name)
                        iv = node.pop(config.iv_field_name)
                    except KeyError:
                        raise EncryptionError(
                            "Encryption field(s) missing in payload.")

                    oaep_digest_algo = node.pop(
                        config.oaep_padding_digest_algorithm_field_name,
                        config.oaep_padding_digest_algorithm)

                    _remove_fingerprint_from_node(node, config)

                    params = SessionKeyParams(config, encrypted_key, iv,
                                              oaep_digest_algo)
                else:
                    params = _params

                cleanup_node(json_payload, elem, target)

                try:
                    update_node(
                        json_payload, target,
                        _decrypt_bytes(params.key, params.iv_spec,
                                       cipher_text))
                except KeyError:
                    raise EncryptionError("Field '" + target + "' not found!")

            except KeyError:
                pass  # encrypted data node not found, nothing to decrypt

        return json_payload

    except json.JSONDecodeError:  # not a json response - return it as is
        return payload
    except (IOError, ValueError, TypeError) as e:
        raise EncryptionError("Payload decryption failed!", e)
Beispiel #5
0
    def test_populate_node_with_key_params(self):
        params = SessionKeyParams.generate(self._config)
        payload = {"key_params": {}}
        node = payload["key_params"]
        to_test._populate_node_with_key_params(node, self._config, params)

        self.assertEqual(5, len(payload["key_params"].keys()))
        self.assertIsNotNone(payload["key_params"][self._config.iv_field_name])
        self.assertIsNotNone(payload["key_params"][self._config.encrypted_key_field_name])
        self.assertEqual("SHA256", payload["key_params"][self._config.oaep_padding_digest_algorithm_field_name])
        self.assertEqual("761b003c1eade3a5490e5000d37887baa5e6ec0e226c07706e599451fc032a79",
                         payload["key_params"][self._config.encryption_key_fingerprint_field_name])
        self.assertEqual("80810fc13a8319fcf0e2ec322c82a4c304b782cc3ce671176343cfe8160c2279",
                         payload["key_params"][self._config.encryption_certificate_fingerprint_field_name])
    def test_encrypt_payload_when_session_key_params_is_provided(self):
        payload = {"data": {}, "encryptedData": {}}

        params = SessionKeyParams.generate(self._config)
        encrypted_payload = to_test.encrypt_payload(payload, self._config,
                                                    params)

        self.assertNotIn("data", encrypted_payload)
        self.assertIn("encryptedData", encrypted_payload)
        self.assertIn("encryptedValue", encrypted_payload["encryptedData"])
        self.assertEqual(1, len(encrypted_payload["encryptedData"].keys()))
        del payload["encryptedData"]
        self.assertEqual(
            payload,
            to_test.decrypt_payload(encrypted_payload, self._config, params))
Beispiel #7
0
    def test_decrypt_payload_when_session_key_params_is_provided(self):
        self._config._data_encoding = Encoding.HEX

        encrypted_payload = {
            "encryptedData": {
                "encryptedValue": "2867e67545b2f3d0708500a1cea649e3"
            }
        }

        iv_value = "ba574b07248f63756bce778f8a115819"
        encrypted_key = "26687f6d03d27145451d20bdaa29cc199e2533bb9eb7351772e31d1290b98380b43dbf47b9a337cc2ecaff9d3d9fb45305950f13382c5ad822ee6df79e1a57b14a3c58c71090121994a9f771ef96472669671718b55a0fa8d9f76de9e172fedcabbc87d64b5a994899e43abb19afa840269012c397b5b18d4babc0e41c1ad698db98c89121bbe5b2d227cfc5d3c3c87f4f4c8b04b509d326199b39adfbd8bca8bf0a150fcf3c37b9717382af502ad8d4d28b17b91762bf108d34aba0fb40ca410c2ecaeb30d68003af20dce27d9d034e4c557b8104e85f859de0eb709b23f9978869bae545c7f1b62173887eae9e75e4b6d6b4b01d7172ccc8c5774c0db51c24"
        oaep_hashing_algo = "SHA256"

        params = SessionKeyParams(self._config, encrypted_key, iv_value, oaep_hashing_algo)
        payload = to_test.decrypt_payload(encrypted_payload, self._config, params)

        self.assertNotIn("encryptedData", payload)
        self.assertDictEqual({"data": {}}, payload)
def encrypt_payload(payload, config, _params=None):
    """Encrypt some fields of a JSON payload using the given configuration."""

    try:
        json_payload = copy.deepcopy(
            payload) if type(payload) is dict else json.loads(payload)

        for elem, target in config.paths["$"].to_encrypt.items():
            if not _params:
                params = SessionKeyParams.generate(config)
            else:
                params = _params

            try:
                value = pop_node(json_payload, elem)

                try:
                    encrypted_value = _encrypt_value(params.key,
                                                     params.iv_spec, value)
                    crypto_node = get_node(json_payload, target, create=True)
                    crypto_node[
                        config.encrypted_value_field_name] = encode_bytes(
                            encrypted_value, config.data_encoding)

                    if not _params:
                        _populate_node_with_key_params(crypto_node, config,
                                                       params)

                except KeyError:
                    raise EncryptionError("Field " + target + " not found!")

            except KeyError:
                pass  # data-to-encrypt node not found, nothing to encrypt

        return json_payload

    except (IOError, ValueError, TypeError) as e:
        raise EncryptionError("Payload encryption failed!", e)