/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdio.h>
#include <axutil_utils.h>
#include <oxs_ctx.h>
#include <oxs_error.h>
#include <oxs_utility.h>
#include <rampart_encryption.h>
#include <oxs_key.h>
#include <rampart_constants.h>
#include <rampart_handler_util.h>
#include <oxs_tokens.h>
#include <axutil_array_list.h>
#include <oxs_axiom.h>
#include <oxs_asym_ctx.h>
#include <oxs_xml_encryption.h>
#include <oxs_derivation.h>
#include <axis2_key_type.h>
#include <oxs_derivation.h>
#include <rampart_sct_provider_utility.h>
#include <axiom_util.h>

static axis2_status_t AXIS2_CALL
rampart_enc_get_nodes_to_encrypt(
    rampart_context_t *rampart_context,
    const axutil_env_t *env,
    axiom_soap_envelope_t *soap_envelope,
    axutil_array_list_t *nodes_to_encrypt)
{
    axis2_status_t status1 = AXIS2_SUCCESS;
    axis2_status_t status2 = AXIS2_SUCCESS;
    
    status1 = rampart_context_get_nodes_to_encrypt(
        rampart_context, env, soap_envelope, nodes_to_encrypt);

    status2 = rampart_context_get_elements_to_encrypt(
        rampart_context, env, soap_envelope, nodes_to_encrypt);

    if(status1 == AXIS2_SUCCESS || status2 == AXIS2_SUCCESS)
    {
        return AXIS2_SUCCESS;
    }
    else
    {
        return AXIS2_FAILURE;
    }
}

/**
 * Encrypts the session key using assymmetric encription
 * @param env pointer to environment struct
 * @param session_key the session key to be encrypted
 * @param msg_ctx message context
 * @param rampart_context the rampart context
 * @param sec_node The security element
 * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_enc_encrypt_session_key(
    const axutil_env_t *env,
    oxs_key_t *session_key,
    axis2_msg_ctx_t *msg_ctx,
    rampart_context_t *rampart_context,
    axiom_node_t *sec_node,
    axutil_array_list_t *id_list)
{
    oxs_asym_ctx_t *asym_ctx = NULL;	
    axis2_char_t *enc_asym_algo = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    axis2_bool_t server_side = AXIS2_FALSE;
    rp_property_t *token = NULL;
    rp_property_type_t token_type;
    axis2_char_t *eki = NULL;
	oxs_x509_cert_t *certificate = NULL; 
    
    server_side = axis2_msg_ctx_get_server_side(msg_ctx, env);
    token = rampart_context_get_token(rampart_context, env, AXIS2_TRUE, server_side, AXIS2_FALSE);
    token_type = rp_property_get_type(token, env);

    if(!rampart_context_is_token_type_supported(token_type, env))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Specified token type not supported.");
        return AXIS2_FAILURE;
    }
    
    /* Get the asymmetric key encryption algorithm */
    enc_asym_algo = rampart_context_get_enc_asym_algo(rampart_context, env);
 
    /* Get encryption key identifier. This identifier depends on whether we include the token in 
     * the message. */
    if(rampart_context_is_token_include(
        rampart_context, token, token_type, server_side, AXIS2_FALSE, env))
    {
        eki = RAMPART_STR_DIRECT_REFERENCE;
    }
    else
    {
        eki = rampart_context_get_key_identifier(rampart_context, token, env);
    }

    if(!eki)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
            "[rampart] No mechanism for attaching the certificate information.");
        return AXIS2_FAILURE;
    }

    /* Receiver certificate can be in the received message. In that case, we should use it. 
       If it is not there, then can get from key manager */
    if(rampart_context_get_found_cert_in_shp(rampart_context, env))
    {
        certificate = rampart_context_get_receiver_cert_found_in_shp(rampart_context, env);
    }
    else
    {
        oxs_key_mgr_t *key_mgr = NULL;
        key_mgr = rampart_context_get_key_mgr(rampart_context, env);
        certificate = oxs_key_mgr_get_receiver_certificate(key_mgr, env);
    }

    if (!certificate)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart] Receiver certificate cannot be loaded.");
        return AXIS2_FAILURE;
    }

    /* Create asymmetric encryption context and populate algorithm, certificate etc. */
    asym_ctx = oxs_asym_ctx_create(env);
    oxs_asym_ctx_set_algorithm(asym_ctx, env, enc_asym_algo);
    oxs_asym_ctx_set_certificate(asym_ctx, env, certificate);
    oxs_asym_ctx_set_operation(asym_ctx, env,OXS_ASYM_CTX_OPERATION_PUB_ENCRYPT);
    oxs_asym_ctx_set_st_ref_pattern(asym_ctx, env, eki);

    /* Encrypt the session key */
    status = oxs_xml_enc_encrypt_key(env, asym_ctx, sec_node, session_key, id_list);
    oxs_asym_ctx_free(asym_ctx, env);
    asym_ctx = NULL;
    
    if(status != AXIS2_SUCCESS)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart] Session key encryption failed.");
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}

/**
 * Encrypt the message using derived keys. Uses symmetric encryption
 * @param env pointer to environment struct
 * @param msg_ctx message context
 * @param rampart_context rampart context
 * @param soap_envelope the SOAP envelope
 * @param sec_node The security element
 * @return AXIS2_SUCCESS on success, else AXIS2_FAILURE
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_enc_dk_encrypt_message(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    rampart_context_t *rampart_context,
    axiom_soap_envelope_t *soap_envelope,
    axiom_node_t *sec_node)
{
    axis2_status_t status = AXIS2_FAILURE;
    oxs_key_t *session_key = NULL;
    axutil_array_list_t *nodes_to_encrypt = NULL;
    axutil_array_list_t *id_list = NULL;
    axutil_array_list_t *dk_list = NULL;
    axis2_char_t *enc_sym_algo = NULL;
    axis2_char_t *asym_key_id = NULL;
	axis2_bool_t free_asym_key_id = AXIS2_FALSE;
    axiom_node_t *encrypted_key_node = NULL;
    axiom_node_t *key_reference_node = NULL;
    axiom_node_t *sig_node = NULL;
    axiom_node_t *data_ref_list_node = NULL;
    axis2_bool_t use_derived_keys = AXIS2_TRUE;
    axis2_char_t *derived_key_version = NULL;
    axis2_bool_t server_side = AXIS2_FALSE;
    rp_property_t *token = NULL;
    rp_property_type_t token_type;
    rampart_saml_token_t *saml = NULL;
    oxs_key_t *derived_key = NULL;
    axiom_soap_body_t *body = NULL;
    axiom_node_t *body_node = NULL;
    axiom_node_t *body_child_node = NULL;

    axis2_bool_t signature_protection = AXIS2_FALSE;
    int i = 0;
    int j = 0;

    body = axiom_soap_envelope_get_body(soap_envelope, env);
    body_node = axiom_soap_body_get_base_node(body, env);
    body_child_node = axiom_node_get_first_element(body_node, env);

    /* Get nodes to be encrypted */
    nodes_to_encrypt = axutil_array_list_create(env, 0);
    status = rampart_enc_get_nodes_to_encrypt(
        rampart_context, env, soap_envelope, nodes_to_encrypt);

    if(status != AXIS2_SUCCESS)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, 
            "[rampart]Error occured in Adding Encrypted parts.");
        axutil_array_list_free(nodes_to_encrypt, env);
        nodes_to_encrypt = NULL;
        return AXIS2_FAILURE;
    }
    
    /* If the sp:EncryptSignature is ON  &&  We sign before the encryption, 
     * we need to add signature node too. */
    signature_protection = rampart_context_is_encrypt_signature(rampart_context, env);

    /* if nothing to encrypt, then we can return successfully */
    if((axutil_array_list_size(nodes_to_encrypt, env)==0))
    {
        if(!signature_protection)
        {
            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                "[rampart]No parts specified or specified parts can't be found for encryprion.");
			axutil_array_list_free(nodes_to_encrypt, env);
			nodes_to_encrypt = NULL;
            return AXIS2_SUCCESS;
        }
    }

    if(signature_protection)
    {
        if(!(rampart_context_is_encrypt_before_sign(rampart_context, env)))
        {
            /*Sign->Encrypt. Easy. just add the signature node to the list*/
            sig_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_SIGNATURE);
            if(!sig_node)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption]Encrypting signature, Sigature Not found");
                return AXIS2_FAILURE;
            }
            axutil_array_list_add(nodes_to_encrypt, env, sig_node);

            if(rampart_context_is_sig_confirmation_reqd(rampart_context, env))
            {
                axiom_node_t* cur_node = NULL;
                cur_node = axiom_node_get_first_child(sec_node, env);
                while(cur_node)
                {
                    axis2_char_t *cur_local_name = NULL;
                    cur_local_name = axiom_util_get_localname(cur_node, env);

                    if(0 == axutil_strcmp(cur_local_name, OXS_NODE_SIGNATURE_CONFIRMATION))
                    {
                        axutil_array_list_add(nodes_to_encrypt, env, cur_node);
                    }
                    cur_node = axiom_node_get_next_sibling(cur_node, env);
                }
            }
        }
    }

    
    /*Get the symmetric encryption algorithm*/
    enc_sym_algo = rampart_context_get_enc_sym_algo(rampart_context, env);

    /*If not specified set the default*/
    if(!enc_sym_algo ||  (0 == axutil_strcmp(enc_sym_algo, "")))
    {
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                       "[rampart][rampart_encryption] No symmetric algorithm is specified for encryption. Using the default");
        enc_sym_algo = OXS_DEFAULT_SYM_ALGO;
    }

    /*We need to take the decision whether to use derived keys or not*/
    server_side = axis2_msg_ctx_get_server_side(msg_ctx, env);
    token = rampart_context_get_token(rampart_context, env, AXIS2_TRUE, server_side, AXIS2_FALSE);
    token_type = rp_property_get_type(token, env);
    use_derived_keys = rampart_context_check_is_derived_keys (env, token);
    derived_key_version = rampart_context_get_derived_key_version(env, token);

    if(token_type == RP_PROPERTY_SAML_TOKEN)
    {
        /* We need to obtain the saml here because it is used in many parts of the code*/
        saml = rampart_context_get_saml_token(rampart_context, env, RAMPART_ST_TYPE_ENCRYPTION_TOKEN);
		if (!saml)
		{
			saml = rampart_context_get_saml_token(rampart_context, env, RAMPART_ST_TYPE_PROTECTION_TOKEN);
		}
        if (!saml)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_encryption] SAML not set.");                
            return AXIS2_FAILURE;
        }
    }
    session_key = rampart_context_get_encryption_session_key(rampart_context, env);
    if(!session_key)
    {
        /*Generate the  session key. if security context token, get the 
        shared secret and create the session key.*/
        if(token_type == RP_PROPERTY_SECURITY_CONTEXT_TOKEN)
        {
            oxs_buffer_t *key_buf = NULL;
            session_key = oxs_key_create(env);
            key_buf = sct_provider_get_secret(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
            if(!key_buf)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption]Cannot get shared secret of security context token");
                oxs_key_free(session_key, env);
                return AXIS2_FAILURE;
            }
            oxs_key_populate(session_key, env,
                   oxs_buffer_get_data(key_buf, env), "for-algo",
                   oxs_buffer_get_size(key_buf, env), OXS_KEY_USAGE_NONE);
            rampart_context_set_encryption_session_key(rampart_context, env, session_key);
        }
        else if(token_type == RP_PROPERTY_SAML_TOKEN)
        {			
			session_key = rampart_saml_token_get_session_key(saml, env);
			if (!session_key)
			{
				AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption] SAML session key not specified.");                
                return AXIS2_FAILURE;
			}
            rampart_context_set_encryption_session_key(rampart_context, env, session_key);
        }
        else
        {
            axis2_char_t *token_id = NULL;
            token_id = rampart_context_get_encryption_token_id(rampart_context, env, msg_ctx);
            if(token_id)
            {
                session_key = rampart_context_get_key(rampart_context, env, token_id);
                oxs_key_set_usage(session_key, env, OXS_KEY_USAGE_SESSION);
            }
            else
            {
                session_key = oxs_key_create(env);
                status = oxs_key_for_algo(session_key, env, rampart_context_get_algorithmsuite(rampart_context, env));
                rampart_context_set_encryption_session_key(rampart_context, env, session_key);
            }
        }
    }

    id_list = axutil_array_list_create(env, 5);
    dk_list = axutil_array_list_create(env, 5);
    /* For each and every encryption part.
        1. Derive a new key if key derivation is enabled. Or else use the same session key
        2. Encrypt using that key       
     */

    /*Add ReferenceList element to the Security header. Note that we pass the sec_node. Not the EncryptedKey*/
    data_ref_list_node = oxs_token_build_reference_list_element(env, sec_node);

    /*create derived key. */
    if(AXIS2_TRUE == use_derived_keys)
    {
        /*Derive a new key*/
        derived_key = oxs_key_create(env);
        oxs_key_set_length(derived_key, env, rampart_context_get_encryption_derived_key_len(rampart_context, env));
        status = oxs_derivation_derive_key(env, session_key, derived_key, AXIS2_TRUE); 
        
        /*Add derived key to the list. We will create tokens*/
        axutil_array_list_add(dk_list, env, derived_key);
        key_reference_node = NULL;
    }

    /*Repeat until all encryption parts are encrypted*/
    for(i=0 ; i < axutil_array_list_size(nodes_to_encrypt, env); i++)
    {
        axiom_node_t *node_to_enc = NULL;
        oxs_ctx_t *enc_ctx = NULL;
#if 0
        oxs_key_t *derived_key = NULL;
#endif
        axis2_char_t *enc_data_id = NULL;
        axiom_node_t *parent_of_node_to_enc = NULL;
        axiom_node_t *enc_data_node = NULL;

        /*Get the node to be encrypted*/
        node_to_enc = (axiom_node_t *)axutil_array_list_get
                      (nodes_to_encrypt, env, i);
    
        /*Create the encryption context for OMXMLSEC*/
        enc_ctx = oxs_ctx_create(env);

        if(AXIS2_TRUE == use_derived_keys)
        {
#if 0
            /*Derive a new key*/
            derived_key = oxs_key_create(env);
            oxs_key_set_length(derived_key, env, rampart_context_get_encryption_derived_key_len(rampart_context, env));
            status = oxs_derivation_derive_key(env, session_key, derived_key, AXIS2_TRUE); 
#endif
            /*Set the derived key for the encryption*/
            oxs_ctx_set_key(enc_ctx, env, derived_key);

            /*Set the ref key name to build KeyInfo element. Here the key name is the derived key id*/
            oxs_ctx_set_ref_key_name(enc_ctx, env, oxs_key_get_name(derived_key, env));
#if 0            
            /*Add derived key to the list. We will create tokens*/
            axutil_array_list_add(dk_list, env, derived_key);
            key_reference_node = NULL;
#endif
        }
        else
        {
            /*No key derivation. We use the same session key*/
            oxs_ctx_set_key(enc_ctx, env, session_key);
            oxs_ctx_set_ref_key_name(enc_ctx, env, oxs_key_get_name(session_key, env));

            if (token_type == RP_PROPERTY_SECURITY_CONTEXT_TOKEN)
            {
                if(rampart_context_is_token_include(rampart_context,
                                                token, token_type, server_side, AXIS2_FALSE, env))
                {
                    /*set the AttachedReference to key_reference_node*/
                    key_reference_node = sct_provider_get_attached_reference(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
                }
                else
                {
                    /*get the unattachedReference and set to key_reference_node*/
                    key_reference_node = sct_provider_get_unattached_reference(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
                }
            }
            else if (token_type == RP_PROPERTY_SAML_TOKEN)
            {
                if(rampart_context_is_token_include(rampart_context,
                                                token, token_type, server_side, AXIS2_FALSE, env))
                {
					axiom_node_t *assertion = NULL;
                    /*set the AttachedReference to key_reference_node*/
                    key_reference_node = rampart_saml_token_get_str(saml, env);						
					if (!key_reference_node)
					{
						assertion = rampart_saml_token_get_assertion(saml, env);
						key_reference_node = oxs_saml_token_build_key_identifier_reference_local(env, NULL, assertion);
					}
                }
                else
                {                    
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption] SAML session key not specified.");                
                    return AXIS2_FAILURE;                    
                }
            }
            else
            {
                if(server_side)
                {
                    axis2_char_t *encrypted_key_hash = NULL;
                    axiom_node_t *identifier_token = NULL;
                    encrypted_key_hash = oxs_key_get_key_sha(session_key, env);
                    key_reference_node = oxs_token_build_security_token_reference_element(env, NULL); 
                    identifier_token = oxs_token_build_key_identifier_element(env, key_reference_node, 
                                        OXS_ENCODING_BASE64BINARY, OXS_X509_ENCRYPTED_KEY_SHA1, encrypted_key_hash);
                }
                else
                {
                    key_reference_node = NULL;
                }
            }
        }

        /*Set the algorithm*/
        oxs_ctx_set_enc_mtd_algorithm(enc_ctx, env, enc_sym_algo);  

        /*Generate ID for the encrypted data ielement*/       
        parent_of_node_to_enc = axiom_node_get_parent(node_to_enc, env);
        enc_data_id = oxs_util_generate_id(env, (axis2_char_t*)OXS_ENCDATA_ID);
 
        if(parent_of_node_to_enc || enc_data_id)
        {
            axis2_char_t *enc_type = OXS_TYPE_ENC_ELEMENT;

            if(body_child_node == node_to_enc)
            {
                /* we have to use #Content for body encryption */
                enc_type = OXS_TYPE_ENC_CONTENT;
            }

            enc_data_node = oxs_token_build_encrypted_data_element(env,
                            parent_of_node_to_enc, enc_type, enc_data_id );
            status = oxs_xml_enc_encrypt_node(env, enc_ctx,
                                                  node_to_enc, &enc_data_node, key_reference_node);
            /*Add Ids to the list. We will create reference list*/
            axutil_array_list_add(id_list, env, enc_data_id);

            if(AXIS2_FAILURE == status)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption] Cannot encrypt the node " );
				for(j=0 ; j < axutil_array_list_size(id_list, env); j++)
				{
					axis2_char_t *id = NULL;
					id = (axis2_char_t *)axutil_array_list_get(id_list, env, j);
					AXIS2_FREE(env->allocator, id);
				}
				axutil_array_list_free(id_list, env);
				id_list = NULL; 

                return AXIS2_FAILURE;
            }

        }
        oxs_ctx_free(enc_ctx, env);
        enc_ctx = NULL;
        
    }/*End of for loop. Iterating nodes_to_encrypt list*/
    
    /*Free node list*/
    axutil_array_list_free(nodes_to_encrypt, env);
    nodes_to_encrypt = NULL;

    if (token_type == RP_PROPERTY_SECURITY_CONTEXT_TOKEN)
    {
        if(rampart_context_is_token_include(rampart_context,
                                        token, token_type, server_side, AXIS2_FALSE, env))
        {
            axiom_node_t *security_context_token_node = NULL;
            /*include the security context token*/
            security_context_token_node = oxs_axiom_get_node_by_local_name(env, sec_node,  OXS_NODE_SECURITY_CONTEXT_TOKEN);
            if((!security_context_token_node) || (rampart_context_is_different_session_key_for_enc_and_sign(env, rampart_context)))
            {
                security_context_token_node = sct_provider_get_token(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
                if(!security_context_token_node)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption] Cannot get security context token");
			        for(j=0 ; j < axutil_array_list_size(id_list, env); j++)
			        {
				        axis2_char_t *id = NULL;
				        id = (axis2_char_t *)axutil_array_list_get(id_list, env, j);
				        AXIS2_FREE(env->allocator, id);
			        }
			        axutil_array_list_free(id_list, env);
			        id_list = NULL;
                    return AXIS2_FAILURE;
                }
                axiom_node_add_child(sec_node, env, security_context_token_node);
            }
        }
    }
    else if (token_type == RP_PROPERTY_SAML_TOKEN)
    {
        if(rampart_context_is_token_include(rampart_context,
                                        token, token_type, server_side, AXIS2_FALSE, env))
        {
            axiom_node_t *assertion = NULL;
            /*include the security context token*/            
            if (!rampart_saml_token_is_added_to_header(saml, env))
                assertion = rampart_saml_token_get_assertion(saml, env);
                if(!assertion)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption] Cannot get SAML token");
			        for(j=0 ; j < axutil_array_list_size(id_list, env); j++)
			        {
				        axis2_char_t *id = NULL;
				        id = (axis2_char_t *)axutil_array_list_get(id_list, env, j);
				        AXIS2_FREE(env->allocator, id);
			        }
			        axutil_array_list_free(id_list, env);
			        id_list = NULL;
                    return AXIS2_FAILURE;
                }
                axiom_node_add_child(sec_node, env, assertion);
        }        
    }
    else
    {
        /* If not done already, Encrypt the session key using the Public Key of the recipient*/
        /* Note: Here we do not send the id_list to create a ReferenceList inside the encrypted key. Instead we create the 
         *       ReferenceList as a child of Security element */
        if(!server_side)
        {
            encrypted_key_node = oxs_axiom_get_node_by_local_name(env, sec_node,  OXS_NODE_ENCRYPTED_KEY);
            if(!encrypted_key_node)
            {
                /*Create EncryptedKey element*/
                status = rampart_enc_encrypt_session_key(env, session_key, msg_ctx, rampart_context, sec_node, NULL );
                if(AXIS2_FAILURE == status)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                        "[rampart][rampart_encryption] Cannot encrypt the session key " );
			        for(j=0 ; j < axutil_array_list_size(id_list, env); j++)
			        {
				        axis2_char_t *id = NULL;
				        id = (axis2_char_t *)axutil_array_list_get(id_list, env, j);
				        AXIS2_FREE(env->allocator, id);
			        }
			        axutil_array_list_free(id_list, env);
			        id_list = NULL;
                    return AXIS2_FAILURE;
                }
                /*Now we have en EncryptedKey Node*/
                encrypted_key_node = oxs_axiom_get_node_by_local_name(env, sec_node,  OXS_NODE_ENCRYPTED_KEY);

                /*Get the asym key Id*/
                if(!encrypted_key_node)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption]Encrypting signature, EncryptedKey Not found");
			        for(j=0 ; j < axutil_array_list_size(id_list, env); j++)
			        {
				        axis2_char_t *id = NULL;
				        id = (axis2_char_t *)axutil_array_list_get(id_list, env, j);
				        AXIS2_FREE(env->allocator, id);
			        }
			        axutil_array_list_free(id_list, env);
			        id_list = NULL;
                    return AXIS2_FAILURE;
                }
                asym_key_id = oxs_util_generate_id(env, (axis2_char_t*)OXS_ENCKEY_ID);
		        free_asym_key_id = AXIS2_TRUE;
                if(asym_key_id)
                {
                    oxs_axiom_add_attribute(env, encrypted_key_node, NULL,
                                        NULL, OXS_ATTR_ID, asym_key_id);
                }
            }
            else
            {
                /*OK Buddy we have already created EncryptedKey node. Get the Id */
                asym_key_id = oxs_axiom_get_attribute_value_of_node_by_name(env, encrypted_key_node, OXS_ATTR_ID, NULL);
            }
        }
    }

    /*Add used <wsc:DerivedKeyToken> elements to the header*/
    for(j=0 ; j < axutil_array_list_size(dk_list, env); j++){
        oxs_key_t *dk = NULL;
        
        dk = (oxs_key_t *)axutil_array_list_get(dk_list, env, j);
        
        /*Build the <wsc:DerivedKeyToken> element*/
        if(dk)
        {
            axiom_node_t *dk_node = NULL;
            if (token_type == RP_PROPERTY_SECURITY_CONTEXT_TOKEN)
            {
               if(rampart_context_is_token_include(rampart_context,
                                                    token, token_type, server_side, AXIS2_FALSE, env))
                {
                    /*set the AttachedReference to key_reference_node*/
                    key_reference_node = sct_provider_get_attached_reference(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
                }
                else
                {
                    /*get the unattachedReference and set to key_reference_node*/
                    key_reference_node = sct_provider_get_unattached_reference(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
                }
                dk_node = oxs_derivation_build_derived_key_token_with_stre(env, dk, sec_node, key_reference_node, derived_key_version);
            }
            else
            {
                if(server_side)
                {
                    axis2_char_t *encrypted_key_hash = NULL;
                    axiom_node_t *identifier_token = NULL;
                    encrypted_key_hash = oxs_key_get_key_sha(session_key, env);
                    key_reference_node = oxs_token_build_security_token_reference_element(env, NULL); 
                    identifier_token = oxs_token_build_key_identifier_element(env, key_reference_node, 
                                        OXS_ENCODING_BASE64BINARY, OXS_X509_ENCRYPTED_KEY_SHA1, encrypted_key_hash);
                    dk_node = oxs_derivation_build_derived_key_token_with_stre(env, dk, sec_node, key_reference_node, derived_key_version);
                }
                else
                {
                    dk_node = oxs_derivation_build_derived_key_token(env, dk, sec_node, asym_key_id, OXS_WSS_11_VALUE_TYPE_ENCRYPTED_KEY, derived_key_version);
                }
            }

            /*derived key should appear before ReferenceList*/
            oxs_axiom_interchange_nodes(env, dk_node, data_ref_list_node);
        }

        /*We will free DK here*/
        oxs_key_free(dk, env);
        dk = NULL;
    
    }/*End of For loop of dk_list iteration*/
    
    /*Free derrived key list*/
    axutil_array_list_free(dk_list, env);
    dk_list = NULL;

    /*Free derrived Id list*/
	for(j=0 ; j < axutil_array_list_size(id_list, env); j++)
	{
		axis2_char_t *id = NULL;
        axis2_char_t* mod_id = NULL;
		id = (axis2_char_t *)axutil_array_list_get(id_list, env, j);
        mod_id = axutil_stracat(env, OXS_LOCAL_REFERENCE_PREFIX,id);
        oxs_token_build_data_reference_element(env, data_ref_list_node, mod_id);
        /*if x509 is used and no-derived keys, then we have to modify security token reference*/
        if((token_type == RP_PROPERTY_X509_TOKEN) && (!use_derived_keys) && (asym_key_id))
        {
            axiom_node_t *enc_data_node = NULL;
            axiom_node_t *envelope_node = NULL;
            axiom_node_t *str_node = NULL;
            axiom_node_t *reference_node = NULL;
            axis2_char_t *id_ref = NULL;

            envelope_node = axiom_soap_envelope_get_base_node(soap_envelope, env);
            enc_data_node = oxs_axiom_get_node_by_id(env, envelope_node, OXS_ATTR_ID, id, NULL);
            str_node = oxs_axiom_get_node_by_local_name(env, enc_data_node, OXS_NODE_SECURITY_TOKEN_REFRENCE);
            reference_node = oxs_axiom_get_node_by_local_name(env, str_node, OXS_NODE_REFERENCE);
            reference_node = axiom_node_detach(reference_node, env);
            axiom_node_free_tree(reference_node, env);
            
            id_ref = axutil_stracat(env, OXS_LOCAL_REFERENCE_PREFIX,asym_key_id);
            reference_node = oxs_token_build_reference_element(env, str_node,
                                id_ref, OXS_WSS_11_VALUE_TYPE_ENCRYPTED_KEY);

            AXIS2_FREE(env->allocator, id_ref);
        }

		AXIS2_FREE(env->allocator, id);
		AXIS2_FREE(env->allocator, mod_id);
	}
    axutil_array_list_free(id_list, env);
    id_list = NULL; 
    
	if(free_asym_key_id && asym_key_id)
	{
		AXIS2_FREE(env->allocator, asym_key_id);
	}

    return status;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_enc_encrypt_message(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    rampart_context_t *rampart_context,
    axiom_soap_envelope_t *soap_envelope,
    axiom_node_t *sec_node)
{

    axutil_array_list_t *nodes_to_encrypt = NULL;
    axutil_array_list_t *id_list = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    axis2_char_t *enc_sym_algo = NULL;
    oxs_key_t *session_key = NULL;
    axis2_bool_t server_side = AXIS2_FALSE;
    rp_property_type_t token_type;
    rp_property_t *token = NULL;
    int i = 0;
    axis2_bool_t signature_protection = AXIS2_FALSE;
    axiom_node_t *sig_node = NULL;
    axiom_soap_body_t *body = NULL;
    axiom_node_t *body_node = NULL;
    axiom_node_t *body_child_node = NULL;

    body = axiom_soap_envelope_get_body(soap_envelope, env);
    body_node = axiom_soap_body_get_base_node(body, env);
    body_child_node = axiom_node_get_first_element(body_node, env);


    /*Get nodes to be encrypted*/

    server_side = axis2_msg_ctx_get_server_side(msg_ctx, env);
    nodes_to_encrypt = axutil_array_list_create(env, 0);

    signature_protection = rampart_context_is_encrypt_signature(
                               rampart_context, env);

    status = rampart_enc_get_nodes_to_encrypt(
                 rampart_context, env, soap_envelope, nodes_to_encrypt);

    if(status != AXIS2_SUCCESS)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_signature]Error occured in Adding Encrypted parts..");
        axutil_array_list_free(nodes_to_encrypt, env);
        nodes_to_encrypt = NULL;
        return AXIS2_FAILURE;
    }

    if((axutil_array_list_size(nodes_to_encrypt, env)==0))
    {
        if(!signature_protection)
        {
            AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                           "[rampart][rampart_encryption] No parts specified or specified parts can't be found for encryprion.");
			axutil_array_list_free(nodes_to_encrypt, env);
			nodes_to_encrypt = NULL;
            return AXIS2_SUCCESS;
        }
    }

    if(signature_protection)
    {
        if(!(rampart_context_is_encrypt_before_sign(rampart_context, env)))
        {
            sig_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_SIGNATURE);
            if(!sig_node)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption]Encrypting signature, Sigature Not found");
				axutil_array_list_free(nodes_to_encrypt, env);
				nodes_to_encrypt = NULL;
                return AXIS2_FAILURE;
            }
            axutil_array_list_add(nodes_to_encrypt, env, sig_node);
        }
    }

    /*Now we have to check whether a token is specified.*/
    token = rampart_context_get_token(rampart_context, env,
                                      AXIS2_TRUE, server_side, AXIS2_FALSE);
    if(!token)
    {
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                       "[rampart][rampart_encryption]Encryption Token is not specified");
		axutil_array_list_free(nodes_to_encrypt, env);
		nodes_to_encrypt = NULL;
        return AXIS2_SUCCESS;
    }
    token_type = rp_property_get_type(token, env);

    if(!rampart_context_is_token_type_supported(token_type, env))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption]Specified token type not supported.");
		axutil_array_list_free(nodes_to_encrypt, env);
		nodes_to_encrypt = NULL;
        return AXIS2_FAILURE;
    }
    if(rampart_context_check_is_derived_keys(env,token))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption]We still do not support derived keys");
		axutil_array_list_free(nodes_to_encrypt, env);
		nodes_to_encrypt = NULL;
        return AXIS2_FAILURE;
    }

    /*Get the symmetric encryption algorithm*/
    enc_sym_algo = rampart_context_get_enc_sym_algo(rampart_context, env);

    /*If not specified set the default*/
    if(!enc_sym_algo ||  (0 == axutil_strcmp(enc_sym_algo, "")))
    {
        AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI,
                       "[rampart][rampart_encryption]No symmetric algorithm is specified for encryption. Using the default");
        enc_sym_algo = OXS_DEFAULT_SYM_ALGO;
    }

    session_key = rampart_context_get_encryption_session_key(rampart_context, env);
    if(!session_key){
        /*Generate the  session key*/
         session_key = oxs_key_create(env);
         status = oxs_key_for_algo(session_key, env, rampart_context_get_algorithmsuite(rampart_context, env));
         rampart_context_set_encryption_session_key(rampart_context, env, session_key);
    }
    if(AXIS2_FAILURE == status)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption] Cannot generate the key for the algorithm %s, ", enc_sym_algo);
		axutil_array_list_free(nodes_to_encrypt, env);
		nodes_to_encrypt = NULL;
        return AXIS2_FAILURE;
    }

    /*Key will be duplicated inside the function. So no worries freeing it here*/
    /*if(rampart_context_is_encrypt_before_sign(rampart_context, env)
            && signature_protection)
    {
        rampart_context_set_session_key(rampart_context, env, session_key);
    }*/

    /*Create a list to store EncDataIds. This will be used in building the ReferenceList*/

    id_list = axutil_array_list_create(env, 5);

    /*Repeat until all encryption parts are encrypted*/
    for(i=0 ; i < axutil_array_list_size(nodes_to_encrypt, env); i++)
    {
        axiom_node_t *node_to_enc = NULL;
        axiom_node_t *parent_of_node_to_enc = NULL;
        axiom_node_t *enc_data_node = NULL;
        oxs_ctx_t *enc_ctx = NULL;
        axis2_char_t *id = NULL;
        axis2_status_t enc_status = AXIS2_FAILURE;

        /*Get the node to be encrypted*/
        node_to_enc = (axiom_node_t *)axutil_array_list_get
                      (nodes_to_encrypt, env, i);
        if(!node_to_enc)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_encryption] Cannot get the node from the list to encrypt");
			axutil_array_list_free(nodes_to_encrypt, env);
			nodes_to_encrypt = NULL;
            return AXIS2_FAILURE;
        }
        /*Create the encryption context for OMXMLSEC*/
        enc_ctx = oxs_ctx_create(env);
        /*Set the key*/
        oxs_ctx_set_key(enc_ctx, env, session_key);
        /*Set the algorithm*/
        oxs_ctx_set_enc_mtd_algorithm(enc_ctx, env, enc_sym_algo);
        /*Create an empty EncryptedDataNode*/
        parent_of_node_to_enc = axiom_node_get_parent(node_to_enc, env);
        id = oxs_util_generate_id(env, (axis2_char_t*)OXS_ENCDATA_ID);

        if(parent_of_node_to_enc || id)
        {
            axis2_char_t *enc_type = OXS_TYPE_ENC_ELEMENT;

            if(body_child_node == node_to_enc)
            {
                /* we have to use #Content for body encryption */
                enc_type = OXS_TYPE_ENC_CONTENT;
            }

            enc_data_node = oxs_token_build_encrypted_data_element(env,
                            parent_of_node_to_enc, enc_type, id );
            enc_status = oxs_xml_enc_encrypt_node(env, enc_ctx,
                                                  node_to_enc, &enc_data_node, NULL); 
            axutil_array_list_add(id_list, env, id);
            if(AXIS2_FAILURE == enc_status)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption] Cannot encrypt the node " );
				axutil_array_list_free(nodes_to_encrypt, env);
				nodes_to_encrypt = NULL;
                return AXIS2_FAILURE;
            }
        }
        oxs_ctx_free(enc_ctx, env);
        enc_ctx = NULL;

    }/*Eof For loop*/

    /*free nodes_to_encrypt list*/
    axutil_array_list_free(nodes_to_encrypt, env);
    nodes_to_encrypt = NULL;

    /*We need to encrypt the session key.*/
    status = rampart_enc_encrypt_session_key(env, session_key, msg_ctx, rampart_context, sec_node, id_list);
    if(AXIS2_FAILURE == status){
        return AXIS2_FAILURE;
    }
    /*Free id_list*/
    if(id_list)
    {
        int size = 0;
        int j = 0;
        size = axutil_array_list_size(id_list, env);
        for (j = 0; j < size; j++)
        {
            axis2_char_t *id = NULL;

            id = axutil_array_list_get(id_list, env, j);
            AXIS2_FREE(env->allocator, id);
            id = NULL;
        }
        axutil_array_list_free(id_list, env);
        id_list = NULL;
    }

    return AXIS2_SUCCESS;
}


AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_enc_add_key_info(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    rampart_context_t *rampart_context,
    axiom_soap_envelope_t *soap_envelope,
    axiom_node_t *sec_node)
{

    axis2_char_t *key_id = NULL;
    axiom_node_t *key_info_node = NULL;
    axiom_node_t *str_node = NULL;
    axiom_node_t *reference_node = NULL;

    axiom_node_t *encrypted_data_node = NULL;
    axiom_node_t *encrypted_key_node = NULL;
    axiom_node_t *body_node = NULL;
    axiom_soap_body_t *body = NULL;

    axiom_element_t *body_ele = NULL;
    axiom_element_t *encrypted_data_ele = NULL;

    encrypted_key_node = oxs_axiom_get_node_by_local_name(
                             env, sec_node,  OXS_NODE_ENCRYPTED_KEY);
    if(!encrypted_key_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption]Encrypting signature, EncryptedKey Not found");
        return AXIS2_FAILURE;
    }

    key_id = oxs_util_generate_id(env, (axis2_char_t*)OXS_ENCKEY_ID);

    if(key_id)
    {
        oxs_axiom_add_attribute(env, encrypted_key_node, NULL/*OXS_WSU*/,
                                NULL/*RAMPART_WSU_XMLNS*/, OXS_ATTR_ID, key_id);
    }

    body = axiom_soap_envelope_get_body(soap_envelope, env);
    body_node = axiom_soap_body_get_base_node(body, env);

    body_ele = (axiom_element_t *)
               axiom_node_get_data_element(body_node, env);

    encrypted_data_ele = axiom_util_get_first_child_element_with_localname(
                             body_ele, env, body_node, OXS_NODE_ENCRYPTED_DATA, &encrypted_data_node);

    if(encrypted_data_ele)
    {
        key_info_node = oxs_token_build_key_info_element(
                            env, encrypted_data_node);
        if(key_info_node)
        {
            str_node = oxs_token_build_security_token_reference_element(
                           env, key_info_node);
            if(str_node)
            {
                axis2_char_t *key_id_ref = NULL;
                key_id_ref = axutil_stracat(env, OXS_LOCAL_REFERENCE_PREFIX,key_id);
                reference_node = oxs_token_build_reference_element(
                                     env, str_node, key_id_ref, NULL);
                AXIS2_FREE(env->allocator, key_id_ref);
                key_id_ref = NULL;
				AXIS2_FREE(env->allocator, key_id);
				key_id = NULL;

                if(!reference_node)
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                    "[rampart][rampart_encryption]Encrypting signature, Reference Node build failed");
                    return AXIS2_FAILURE;
                }
                else
                {
                    return AXIS2_SUCCESS;
                }
            }
            else{
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption]Encrypting signature, Cannot build the STR node");
				AXIS2_FREE(env->allocator, key_id);
				key_id = NULL;
                return AXIS2_FAILURE;
            }
        }
        else{
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_encryption] Encrypting signature, cannot build the key indfo node");
			AXIS2_FREE(env->allocator, key_id);
			key_id = NULL;
            return AXIS2_FAILURE;
        }
    }
    else{
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption]Encrypting signature, Cannot get the encryption data element");
		AXIS2_FREE(env->allocator, key_id);
		key_id = NULL;
        return AXIS2_FAILURE;
    }
}


AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_enc_encrypt_signature(
    const axutil_env_t *env,
    axis2_msg_ctx_t *msg_ctx,
    rampart_context_t *rampart_context,
    axiom_soap_envelope_t *soap_envelope,
    axiom_node_t *sec_node)
{

    oxs_key_t *session_key = NULL;
    oxs_key_t *derived_key = NULL;
    axiom_node_t *node_to_enc = NULL;
    axiom_node_t *enc_data_node = NULL;
    oxs_ctx_t *enc_ctx = NULL;
    axis2_char_t *id = NULL;
    axis2_status_t enc_status = AXIS2_FAILURE;
    axis2_char_t *enc_sym_algo = NULL;
    axutil_array_list_t *id_list = NULL;
    axiom_node_t *encrypted_key_node = NULL;
    axiom_node_t *temp_node = NULL;
    axiom_node_t *node_to_move = NULL;
    axis2_bool_t use_derived_keys = AXIS2_TRUE;
    axis2_char_t *derived_key_version = NULL;
    axis2_bool_t server_side = AXIS2_FALSE;
    rp_property_t *token = NULL;
    rp_property_type_t token_type;
    axis2_status_t status = AXIS2_FAILURE;
    axiom_node_t *key_reference_node = NULL;
    axiom_node_t *key_reference_for_encrypted_data = NULL;
    rampart_saml_token_t *saml = NULL;

    session_key = rampart_context_get_encryption_session_key(rampart_context, env);

    if(!session_key)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption]Encrypting Signature.Session key not found");
        return AXIS2_FAILURE;
    }
    /*Get <ds:Signature> node*/
    node_to_enc = oxs_axiom_get_node_by_local_name(
                      env, sec_node, OXS_NODE_SIGNATURE);

    if(!node_to_enc)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption]Encrypting Signature. Signature node not found");
        return AXIS2_FAILURE;
    }

    server_side = axis2_msg_ctx_get_server_side(msg_ctx, env);
    token = rampart_context_get_token(rampart_context, env, AXIS2_TRUE, server_side, AXIS2_FALSE);
    token_type = rp_property_get_type(token, env);

    if(token_type == RP_PROPERTY_SECURITY_CONTEXT_TOKEN)
    {
        if(rampart_context_is_token_include(rampart_context,
                                        token, token_type, server_side, AXIS2_FALSE, env))
        {
            /*set the AttachedReference to key_reference_node*/
            key_reference_node = sct_provider_get_attached_reference(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
        }
        else
        {
            /*get the unattachedReference and set to key_reference_node*/
            key_reference_node = sct_provider_get_unattached_reference(env, token, AXIS2_TRUE, rampart_context, msg_ctx);
        }
    }
    else if(token_type == RP_PROPERTY_SAML_TOKEN)
    {
        saml = rampart_context_get_saml_token(rampart_context, env, RAMPART_ST_TYPE_ENCRYPTION_TOKEN);
		if (!saml)
		{
			saml = rampart_context_get_saml_token(rampart_context, env, RAMPART_ST_TYPE_PROTECTION_TOKEN);
		}
        if (!saml)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                            "[rampart][rampart_encryption] SAML not set.");                
            return AXIS2_FAILURE;
        }
        if(rampart_context_is_token_include(rampart_context,
                                        token, token_type, server_side, AXIS2_FALSE, env))
        {
            /*set the AttachedReference to key_reference_node*/
            key_reference_node = rampart_saml_token_get_str(saml, env);
        }
        else
        {
            /*get the unattachedReference and set to key_reference_node*/
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "[rampart][rampart_encryption] SAML not set.");                
            return AXIS2_FAILURE;
        }
    }
    else
    {
        if((server_side) && (rampart_context_get_binding_type(rampart_context,env) == RP_PROPERTY_SYMMETRIC_BINDING))
        {
            axis2_char_t *encrypted_key_hash = NULL;
            axiom_node_t *identifier_token = NULL;
            encrypted_key_hash = oxs_key_get_key_sha(session_key, env);
            key_reference_node = oxs_token_build_security_token_reference_element(env, NULL); 
            identifier_token = oxs_token_build_key_identifier_element(env, key_reference_node, 
                                OXS_ENCODING_BASE64BINARY, OXS_X509_ENCRYPTED_KEY_SHA1, encrypted_key_hash);
        }
        else
        {
            encrypted_key_node = oxs_axiom_get_node_by_local_name(
                                     env, sec_node,  OXS_NODE_ENCRYPTED_KEY);
            if(!encrypted_key_node)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption]Encrypting signature, EncryptedKey Not found");
                return AXIS2_FAILURE;
            }
        }
    }

    enc_ctx = oxs_ctx_create(env);

    /*We need to take the decision whether to use derived keys or not*/
    use_derived_keys = rampart_context_check_is_derived_keys (env, token);
    derived_key_version = rampart_context_get_derived_key_version(env, token);
    if(AXIS2_TRUE == use_derived_keys)
    {
        /*Derive a new key*/
        derived_key = oxs_key_create(env);
        oxs_key_set_length(derived_key, env, rampart_context_get_encryption_derived_key_len(rampart_context, env));
        status = oxs_derivation_derive_key(env, session_key, derived_key, AXIS2_TRUE);

        /*Set the derived key for the encryption*/
        oxs_ctx_set_key(enc_ctx, env, derived_key);

        /*Set the ref key name to build KeyInfo element. Here the key name is the derived key id*/
        oxs_ctx_set_ref_key_name(enc_ctx, env, oxs_key_get_name(derived_key, env));
    }
    else
    {
        /*No Key derivation is needed we will proceed with the same session key*/
        oxs_ctx_set_key(enc_ctx, env, session_key);
        key_reference_for_encrypted_data = key_reference_node;
    }
    enc_sym_algo = rampart_context_get_enc_sym_algo(rampart_context, env);
    oxs_ctx_set_enc_mtd_algorithm(enc_ctx, env, enc_sym_algo);
    id = oxs_util_generate_id(env, (axis2_char_t*)OXS_ENCDATA_ID);

    /*Manage the reference list*/
    id_list = axutil_array_list_create(env, 0);
    axutil_array_list_add(id_list, env, id);
    if((rampart_context_get_binding_type(rampart_context,env)) == RP_PROPERTY_ASYMMETRIC_BINDING)
    {
        /*We append IDs to the EncryptedKey node*/
        axiom_node_t *ref_list_node = NULL;
        ref_list_node = oxs_token_build_data_reference_list(
                         env, encrypted_key_node, id_list);
        if(!ref_list_node)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart][rampart_encryption]Asym Encrypting signature,"
                    "Building reference list failed");
            return AXIS2_FAILURE;
        } 
    }
    else if((rampart_context_get_binding_type(rampart_context,env)) == RP_PROPERTY_SYMMETRIC_BINDING)
    {
        if((AXIS2_TRUE == use_derived_keys) || (token_type == RP_PROPERTY_SECURITY_CONTEXT_TOKEN) || (server_side) || 
            (token_type == RP_PROPERTY_SAML_TOKEN))
        {
            /*We need to create a new reference list and then attach it before the EncryptedData(signature)*/
            axiom_node_t *ref_list_node = NULL;

            ref_list_node = oxs_token_build_data_reference_list(env, sec_node, id_list);
            if(!ref_list_node)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart][rampart_encryption]Sym Encrypting signature,"
                                    "Building reference list failed");
                return AXIS2_FAILURE;
            }
        }
        else
        {
            /*The session key is in use. Add a ref to the EncryptedKey's ref list*/
            axiom_node_t *ref_list_node = NULL;
            ref_list_node = oxs_axiom_get_first_child_node_by_name(
                        env, encrypted_key_node, OXS_NODE_REFERENCE_LIST, OXS_ENC_NS, NULL);
            if(ref_list_node)
            {
                /*There is a ref list node in EncryptedKey. So append*/
                axiom_node_t *data_ref_node = NULL;
                axis2_char_t *mod_id = NULL;

                /*We need to prepend # to the id in the list to create the reference*/
                mod_id = axutil_stracat(env, OXS_LOCAL_REFERENCE_PREFIX,id);
                data_ref_node = oxs_token_build_data_reference_element(env, ref_list_node, mod_id);

            }
            else
            {
                /*There is NO ref list node in EncryptedKey. So create a new one */
                ref_list_node = oxs_token_build_data_reference_list(env, encrypted_key_node, id_list);
            }
        }       
    }
    else
    {
        /*Nothing to do*/
    }
    
    /*Encrypt the signature*/
    enc_data_node = oxs_token_build_encrypted_data_element(
                        env, sec_node, OXS_TYPE_ENC_ELEMENT, id );
    enc_status = oxs_xml_enc_encrypt_node(
        env, enc_ctx, node_to_enc, &enc_data_node, key_reference_for_encrypted_data);

    /*FREE*/
    oxs_ctx_free(enc_ctx, env);
    enc_ctx = NULL;

    if(enc_status != AXIS2_SUCCESS)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "[rampart][rampart_encryption] Encrypting node failed");
        return AXIS2_FAILURE;
    }
    /*If we have used a derrived key, we need to attach it to the Securuty Header*/
    if(AXIS2_TRUE == use_derived_keys)
    {
        if((token_type == RP_PROPERTY_SECURITY_CONTEXT_TOKEN) || token_type == RP_PROPERTY_SAML_TOKEN ||
            (server_side && (rampart_context_get_binding_type(rampart_context,env) == RP_PROPERTY_SYMMETRIC_BINDING)))
        {
            oxs_derivation_build_derived_key_token_with_stre(env, derived_key, sec_node, key_reference_node, derived_key_version);
        }
        else
        {
            axis2_char_t *asym_key_id = NULL;
            asym_key_id = oxs_axiom_get_attribute_value_of_node_by_name(env, encrypted_key_node, OXS_ATTR_ID, NULL);
            oxs_derivation_build_derived_key_token(env, derived_key, sec_node, asym_key_id, OXS_WSS_11_VALUE_TYPE_ENCRYPTED_KEY, derived_key_version);  
        }
		/*now we can free the derived key*/
		oxs_key_free(derived_key, env);
		derived_key = NULL;
    }

    node_to_move = oxs_axiom_get_node_by_local_name(
                       env, sec_node,  OXS_NODE_REFERENCE_LIST);

    if(node_to_move)
    {
        temp_node = axiom_node_detach(node_to_move, env);
        if(temp_node)
        {
            enc_status = axiom_node_insert_sibling_after(
                             enc_data_node, env, temp_node);
            if(enc_status != AXIS2_SUCCESS)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                                "[rampart][rampart_encryption]Encrypting signature, Node moving failed.");
                return AXIS2_FAILURE;
            }
        }
    }


    if(id_list)
    {
        /*Need to free data of the list*/
        int size = 0;
        int j = 0;
        size = axutil_array_list_size(id_list, env);
        for (j = 0; j < size; j++)
        {
            axis2_char_t *id_temp = NULL;
            id_temp = axutil_array_list_get(id_list, env, j);
            AXIS2_FREE(env->allocator, id_temp);
            id_temp = NULL;
        }

        axutil_array_list_free(id_list, env);
        id_list = NULL;
    }
    return AXIS2_SUCCESS;
}
