/*
 * 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_qname.h>
#include <axiom_namespace.h>
#include <axiom_node.h>
#include <axiom_util.h>
#include <axiom_element.h>
#include <axis2_util.h>
#include <oxs_tokens.h>
#include <oxs_constants.h>
#include <oxs_axiom.h>
#include <oxs_ctx.h>
#include <oxs_error.h>
#include <oxs_buffer.h>
#include <oxs_cipher.h>
#include <oxs_iv.h>
#include <oxs_utility.h>
#include <oxs_encryption.h>
#include <oxs_xml_encryption.h>
#include <openssl_digest.h>


/*private functions*/

/**
*   <KeyInfo>
*       <SecurityTokenReference>
*           <KeyIdentifier>WEqswOIUsd</KeyIdentifier>
*       </SecurityTokenReference>
*   </KeyInfo>
*   
*/
static axis2_status_t
oxs_xml_enc_populate_stref_with_key_identifier(
    const axutil_env_t *env,
    oxs_asym_ctx_t *asym_ctx,
    axiom_node_t *stref_node,
    axis2_bool_t is_thumbprint)
{
    axiom_node_t *key_identifier_node = NULL;
    axis2_char_t *key_identifier = NULL;
    axis2_char_t *val_type = NULL;
    oxs_x509_cert_t *cert = NULL;

    cert = oxs_asym_ctx_get_certificate(asym_ctx, env);
    if(is_thumbprint)
    {
        key_identifier = oxs_x509_cert_get_fingerprint(cert, env);
        val_type = OXS_X509_TUMBP_PRINT_SHA1;
    }
    else
    {
        key_identifier = oxs_x509_cert_get_key_identifier(cert, env);
        val_type = OXS_X509_SUBJ_KI;
    }
    if(!key_identifier)
    {
        return AXIS2_FAILURE;
    }
    /*Build KeyIdentifier node*/
    key_identifier_node = oxs_token_build_key_identifier_element(env, stref_node,
        OXS_ENCODING_BASE64BINARY, val_type, key_identifier);
    return AXIS2_SUCCESS;
}

/**
*  
*   <BinarySecurityToken ID="CertID">KJDSsdlDJjsd=</BinarySecurityToken>
*   <KeyInfo>
*       <SecurityTokenReference>
*           <Reference URI="CertID"/>
*       </SecurityTokenReference>
*   </KeyInfo>
*/
static axis2_status_t
oxs_xml_enc_populate_stref_with_bst(
    const axutil_env_t *env,
    oxs_asym_ctx_t *asym_ctx,
    axiom_node_t *stref_node,
    axiom_node_t *parent)
{
    axiom_node_t *ref_node = NULL;
    axiom_node_t *bst_node = NULL;
    axis2_char_t *bst_data = NULL;
    axis2_char_t *id = NULL;
    axis2_char_t *ref_id = NULL;
    oxs_x509_cert_t *cert = NULL;

    cert = oxs_asym_ctx_get_certificate(asym_ctx, env);
    bst_data = oxs_x509_cert_get_data(cert, env);

    if(!bst_data)
    {
        return AXIS2_FAILURE;
    }
    /*Generate an ID for BST*/
    id = oxs_util_generate_id(env, (axis2_char_t*)OXS_CERT_ID);

    /*Build BinarySecurityToken as a child of parent(wsse:Security)*/
    bst_node = oxs_token_build_binary_security_token_element(env, parent, id,
        OXS_ENCODING_BASE64BINARY, OXS_VALUE_X509V3, bst_data);

    /*Build a Reference to above BST*/
    ref_id = axutil_stracat(env, OXS_LOCAL_REFERENCE_PREFIX, id);
    ref_node = oxs_token_build_reference_element(env, stref_node, ref_id, OXS_VALUE_X509V3);

    return AXIS2_SUCCESS;
}
/**
*   <KeyInfo>
*       <SecurityTokenReference>
*           <Embedded>
*               <BinarySecurityToken>UYISDjsdaousdWEqswOIUsd</BinarySecurityToken>
*           </Embedded>
*       </SecurityTokenReference>
*   </KeyInfo>
*/
static axis2_status_t
oxs_xml_enc_populate_stref_with_embedded(
    const axutil_env_t *env,
    oxs_asym_ctx_t *asym_ctx,
    axiom_node_t *stref_node)
{
    axiom_node_t *embedded_node = NULL;
    axiom_node_t *bst_node = NULL;
    axis2_char_t *bst_data = NULL;
    oxs_x509_cert_t *cert = NULL;

    cert = oxs_asym_ctx_get_certificate(asym_ctx, env);
    bst_data = oxs_x509_cert_get_data(cert, env);

    if(!bst_data)
    {
        return AXIS2_FAILURE;
    }
    /*Build embedded token*/
    embedded_node = oxs_token_build_embedded_element(env, stref_node, NULL);
    /*Build BinarySecurityToken*/
    bst_node = oxs_token_build_binary_security_token_element(env, embedded_node, NULL,
        OXS_ENCODING_BASE64BINARY, OXS_VALUE_X509V3, bst_data);

    return AXIS2_SUCCESS;
}

/**
*   <KeyInfo>
*       <SecurityTokenReference>
*           <x509Data>
*               <X509IssuerSerial>
*                   <X509IssuerName>C=US, O=VeriSign, Inc.,</X509IssuerName>
*                   <X509SerialNumber>93243297328</X509SerialNumber>
*               </X509IssuerSerial>
*           </x509Data>
*       </SecurityTokenReference>
*   </KeyInfo>
*/
static axis2_status_t
oxs_xml_enc_populate_stref_with_issuer_serial(
    const axutil_env_t *env,
    oxs_asym_ctx_t *asym_ctx,
    axiom_node_t *stref_node)
{
    axiom_node_t *x509_data_node = NULL;
    axiom_node_t *issuer_serial_node = NULL;
    oxs_x509_cert_t *cert = NULL;
    axis2_char_t *issuer_name = NULL;
    axis2_char_t serial_number[255];
    int serial = -1;

    cert = oxs_asym_ctx_get_certificate(asym_ctx, env);

    issuer_name = oxs_x509_cert_get_issuer(cert, env);
    serial = oxs_x509_cert_get_serial_number(cert, env);
    if((!issuer_name) || (serial < 0))
    {
        return AXIS2_FAILURE;
    }

    sprintf(serial_number, "%d", serial);
    /*Build x509Data*/
    x509_data_node = oxs_token_build_x509_data_element(env, stref_node);
    issuer_serial_node = oxs_token_build_x509_issuer_serial_with_data(env, x509_data_node,
        issuer_name, serial_number);
    return AXIS2_SUCCESS;
}

static axis2_status_t
oxs_xml_enc_process_key_info(
    const axutil_env_t *env,
    oxs_asym_ctx_t *asym_ctx,
    axiom_node_t *key_info_node,
    axiom_node_t *parent_node)
{
    axiom_node_t *st_ref_node = NULL;

    st_ref_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,
        OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, OXS_WSSE);
    if(!st_ref_node)
    {
        return AXIS2_FAILURE;
    }
    /*
     WSS-Core specification suggests
     1. Resolve any <wsse:Reference> elements (specified within
     <wsse:SecurityTokenReference>).
     2. Resolve any <wsse:KeyIdentifier> elements (specified within
     <wsse:SecurityTokenReference>).
     3. Resolve any <ds:KeyName> elements. NOT PERMITTED by WS-i
     4. Resolve any other <ds:KeyInfo> elements. NOT PERMITTED by WS-i
     */

    /*
     * TODO: This method should get the key from the key_node. Currently key is taken from 
     * given private key file
     */

    return AXIS2_SUCCESS;
}

/*public functions*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_encrypt_node(
    const axutil_env_t *env,
    oxs_ctx_t * enc_ctx,
    axiom_node_t *node,
    axiom_node_t **enc_type_node,
    axiom_node_t *security_token_reference)
{
    axis2_char_t *serialized_data = NULL;
    oxs_buffer_t *serialized_buf = NULL;
    axis2_status_t ret = AXIS2_FAILURE;

    /*Serialize node*/
    /*serialized_data = axiom_node_to_string(node, env);*/
    serialized_data = axiom_node_to_string_non_optimized(node, env);
    serialized_buf = oxs_buffer_create(env);
    ret = oxs_buffer_populate(serialized_buf, env, (unsigned char *)serialized_data, axutil_strlen(
        serialized_data));

    /*We call encrypt_data*/
    ret = oxs_xml_enc_encrypt_data(env, enc_ctx, serialized_buf, enc_type_node,
        security_token_reference);

    /*Remove the node from the parent*/
    if(AXIS2_SUCCESS == ret)
    {
        axiom_node_detach(node, env);
        axiom_node_free_tree(node, env);
        node = NULL;
    }
    /*Free*/
    oxs_buffer_free(serialized_buf, env);
    serialized_buf = NULL;

    AXIS2_FREE(env->allocator, serialized_data);
    serialized_data = NULL;

    /*Return success*/
    return AXIS2_SUCCESS;
}


AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_encrypt_data(
    const axutil_env_t *env,
    oxs_ctx_t * enc_ctx,
    oxs_buffer_t *content_buf,
    axiom_node_t **enc_type_node,
    axiom_node_t *security_token_reference_node)
{
    oxs_buffer_t *result_buf = NULL;
    oxs_key_t *sym_key = NULL;
    axis2_char_t *sym_algo = NULL;
    axiom_node_t *enc_mtd_node = NULL;
    axiom_node_t *cd_node = NULL;
    axiom_node_t *cv_node = NULL;
    axis2_status_t ret = AXIS2_FAILURE;

    /*Determine the algorithm to be used*/
    sym_algo = oxs_ctx_get_enc_mtd_algorithm(enc_ctx, env);

    /*Determine the key to be used*/
    sym_key = oxs_ctx_get_key(enc_ctx, env);

    /*Set the operation to encrypt*/
    oxs_ctx_set_operation(enc_ctx, env, OXS_CTX_OPERATION_ENCRYPT);

    /*Create an empty buffer for encrypted data*/
    result_buf = oxs_buffer_create(env);
    /*Call encryption. Result should be base64 encoded*/
    ret = oxs_encryption_symmetric_crypt(env, enc_ctx, content_buf, result_buf);

    /*Create EncryptionMethod*/
    enc_mtd_node = oxs_token_build_encryption_method_element(env, *enc_type_node, sym_algo);

    /*If security_token_reference_node is given, then use it to build the key info*/
    /*if we are using any trust/sct related token, then the key reference is given with the token
     *and we are suppose to use it */
    if(security_token_reference_node)
    {
        axiom_node_t *key_info_node = NULL;
        key_info_node = oxs_token_build_key_info_element(env, *enc_type_node);
        axiom_node_add_child(key_info_node, env, security_token_reference_node);
    }
    /*If the enc_ctx has a key name, then build the KeyInfo element using key name*/
    else if(oxs_ctx_get_ref_key_name(enc_ctx, env))
    {
        axiom_node_t *key_info_node = NULL;
        axiom_node_t *str_node = NULL;
        axiom_node_t *ref_node = NULL;

        key_info_node = oxs_token_build_key_info_element(env, *enc_type_node);
        str_node = oxs_token_build_security_token_reference_element(env, key_info_node);
        ref_node = oxs_token_build_reference_element(env, str_node, oxs_ctx_get_ref_key_name(
            enc_ctx, env), NULL);
    }

    /*Create CipherData element and populate*/
    cd_node = oxs_token_build_cipher_data_element(env, *enc_type_node);
    cv_node = oxs_token_build_cipher_value_element(env, cd_node,
        (axis2_char_t*)oxs_buffer_get_data(result_buf, env));

    /*Free buffers*/
    oxs_buffer_free(result_buf, env);
    result_buf = NULL;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_decrypt_node(
    const axutil_env_t *env,
    oxs_ctx_t * enc_ctx,
    axiom_node_t *enc_type_node,
    axiom_node_t **decrypted_node)
{
    axiom_node_t *deserialized_node = NULL;
    axiom_node_t *parent_of_enc_node = NULL;
    oxs_buffer_t *result_buf = NULL;
    axis2_char_t *decrypted_data = NULL;/*Can be either am XML-Element or XML-Content*/
    axis2_status_t status = AXIS2_FAILURE;

    /*Create an empty buffer for results*/
    result_buf = oxs_buffer_create(env);

    /*Decrypt*/
    status = oxs_xml_enc_decrypt_data(env, enc_ctx, enc_type_node, result_buf);
    if(AXIS2_FAILURE == status)
    {
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED, "Data encryption failed");
        return AXIS2_FAILURE;
    }
    decrypted_data = axutil_strmemdup(oxs_buffer_get_data(result_buf, env), oxs_buffer_get_size(
        result_buf, env), env);
    /*De-serialize the decrypted content to build the node*/
    deserialized_node = (axiom_node_t*)oxs_axiom_deserialize_node(env, decrypted_data);
    if(!deserialized_node)
    {
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED,
            "Cannot deserialize a node from the content.\n%s", decrypted_data);
        return AXIS2_FAILURE;
    }
    /*Assign deserialized_node to the reference passed*/
    *decrypted_node = deserialized_node;

    /*Replace the encrypted node with the de-serialized node*/
    parent_of_enc_node = axiom_node_get_parent(enc_type_node, env);

    axiom_node_insert_sibling_after(enc_type_node, env, deserialized_node);
    axiom_node_detach(enc_type_node, env);

    axiom_node_free_tree(enc_type_node, env);
    enc_type_node = NULL;

    /*Free result buf*/

    oxs_buffer_free(result_buf, env);
    result_buf = NULL;

    AXIS2_FREE(env->allocator, decrypted_data);
    decrypted_data = NULL;

    return AXIS2_SUCCESS;
}

AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_decrypt_data(
    const axutil_env_t *env,
    oxs_ctx_t * enc_ctx,
    axiom_node_t *enc_type_node,
    oxs_buffer_t *result_buf)
{
    axiom_node_t *enc_mtd_node = NULL;
    axiom_node_t *cd_node = NULL;
    axiom_node_t *cv_node = NULL;
    axis2_char_t *cipher_val = NULL;
    axis2_char_t *new_cipher_val = NULL;
    axis2_char_t *sym_algo = NULL;
    axis2_char_t *type = NULL;
    axis2_char_t *id = NULL;
    oxs_buffer_t *input_buf = NULL;
    axis2_status_t status = AXIS2_FAILURE;

    /* Get the symmetric encryption algorithm */
    enc_mtd_node = oxs_axiom_get_first_child_node_by_name(env, enc_type_node,
        OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, OXS_XENC);
    if(!enc_mtd_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find encryption method node");
        return AXIS2_FAILURE;
    }

    sym_algo = oxs_token_get_encryption_method(env, enc_mtd_node);
    if(!sym_algo)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find encryption method");
        return AXIS2_FAILURE;
    }

    /* Get ID, Type, MimeType attributes from the EncryptedDataNode */
    id = oxs_axiom_get_attribute_value_of_node_by_name(env, enc_type_node, OXS_ATTR_ID, NULL);
    type = oxs_axiom_get_attribute_value_of_node_by_name(env, enc_type_node, OXS_ATTR_TYPE, NULL);

    /* Populate the context for future use */
    oxs_ctx_set_enc_mtd_algorithm(enc_ctx, env, sym_algo);
    oxs_ctx_set_id(enc_ctx, env, id);
    oxs_ctx_set_type(enc_ctx, env, type);

    /* Get the cipher value */
    cd_node = oxs_axiom_get_first_child_node_by_name(env, enc_type_node, OXS_NODE_CIPHER_DATA,
        OXS_ENC_NS, OXS_XENC);
    if(!cd_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher data node");
        return AXIS2_FAILURE;
    }

    cv_node = oxs_axiom_get_first_child_node_by_name(env, cd_node, OXS_NODE_CIPHER_VALUE,
        OXS_ENC_NS, OXS_XENC);
    if(!cv_node)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher value node");
        return AXIS2_FAILURE;
    }

    cipher_val = oxs_token_get_cipher_value(env, cv_node);
    if(!cipher_val)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher value");
        return AXIS2_FAILURE;
    }

    /* We need to remove new lines if any */
    new_cipher_val = oxs_util_get_newline_removed_string(env, cipher_val);

    /* Create input buffer with cipher data obtained */
    input_buf = oxs_buffer_create(env);
    oxs_buffer_populate(input_buf, env, (unsigned char*)new_cipher_val,
        axutil_strlen(new_cipher_val));

    /* Decrypt */
    oxs_ctx_set_operation(enc_ctx, env, OXS_CTX_OPERATION_DECRYPT);
    status = oxs_encryption_symmetric_crypt(env, enc_ctx, input_buf, result_buf);

    /*Free*/
    oxs_buffer_free(input_buf, env);
    input_buf = NULL;
    AXIS2_FREE(env->allocator, new_cipher_val);
    new_cipher_val = NULL;

    return status;
}

/*For SOAP this parent is the wsse:Security node*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_encrypt_key(
    const axutil_env_t *env,
    oxs_asym_ctx_t * asym_ctx,
    axiom_node_t *parent,
    oxs_key_t *sym_key,
    axutil_array_list_t *id_list)
{
    axis2_char_t *algorithm = NULL;
    axis2_char_t *encrypted_key_data = NULL;
    axis2_char_t *st_ref_pattern = NULL;
    oxs_buffer_t *input = NULL;
    oxs_buffer_t *result = NULL;
    axiom_node_t *encrypted_key_node = NULL;
    axiom_node_t *enc_mtd_node = NULL;
    axiom_node_t *key_info_node = NULL;
    axiom_node_t *stref_node = NULL;
    axiom_node_t *cd_node = NULL;
    axiom_node_t *cv_node = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    axis2_char_t* encrypted_key_hash = NULL;
    int decoded_len = 0;
    axis2_char_t *decoded_enc_sec = NULL;

    /*Create input buffer*/
    input = oxs_buffer_create(env);
    oxs_buffer_populate(input, env, oxs_key_get_data(sym_key, env), oxs_key_get_size(sym_key, env));

    /*Create an empty buffer to collect results*/
    result = oxs_buffer_create(env);

    /*Call encryption*/
    status = oxs_encryption_asymmetric_crypt(env, asym_ctx, input, result);
    /*Free input*/
    oxs_buffer_free(input, env);
    input = NULL;

    if(AXIS2_FAILURE == status)
    {
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED,
            "Assymmetric key encryption failed");
        return AXIS2_FAILURE;
    }
    /*Get the encrypted key*/
    encrypted_key_data = (axis2_char_t *)oxs_buffer_get_data(result, env);

    /*Build nodes*/
    encrypted_key_node = oxs_token_build_encrypted_key_element(env, parent);
    algorithm = oxs_asym_ctx_get_algorithm(asym_ctx, env);
    enc_mtd_node = oxs_token_build_encryption_method_element(env, encrypted_key_node, algorithm);
    key_info_node = oxs_token_build_key_info_element(env, encrypted_key_node);

    stref_node = oxs_token_build_security_token_reference_element(env, key_info_node);
    /*Get the ST REF pattern. If not set the default*/
    st_ref_pattern = oxs_asym_ctx_get_st_ref_pattern(asym_ctx, env);
    if((!st_ref_pattern) || (0 == axutil_strcmp(st_ref_pattern, "")))
    {
        st_ref_pattern = OXS_STR_DEFAULT;
    }

    if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_ISSUER_SERIAL))
    {
        status = oxs_xml_enc_populate_stref_with_issuer_serial(env, asym_ctx, stref_node);
    }
    else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_EMBEDDED))
    {
        status = oxs_xml_enc_populate_stref_with_embedded(env, asym_ctx, stref_node);
    }
    else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_DIRECT_REFERENCE))
    {
        status = oxs_xml_enc_populate_stref_with_bst(env, asym_ctx, stref_node, parent);
    }
    else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_KEY_IDENTIFIER))
    {
        status = oxs_xml_enc_populate_stref_with_key_identifier(env, asym_ctx, stref_node,
            AXIS2_FALSE);
    }
    else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_THUMB_PRINT))
    {
        /*TODO: Need to support Thumbprint Ref*/
        status = oxs_xml_enc_populate_stref_with_key_identifier(env, asym_ctx, stref_node,
            AXIS2_TRUE);
    }
    cd_node = oxs_token_build_cipher_data_element(env, encrypted_key_node);
    cv_node = oxs_token_build_cipher_value_element(env, cd_node, encrypted_key_data);
    /*If and only if the id_list the present, we create the reference list*/
    if(id_list)
    {
        oxs_token_build_data_reference_list(env, encrypted_key_node, id_list);
    }

    /*calculate the EncryptedKeySHA1 and set as the key_sha*/
    decoded_len = axutil_base64_decode_len(encrypted_key_data);
    decoded_enc_sec = AXIS2_MALLOC(env->allocator, decoded_len);
    axutil_base64_decode_binary((unsigned char*)decoded_enc_sec, encrypted_key_data);
    encrypted_key_hash = openssl_sha1(env, decoded_enc_sec, decoded_len);
    oxs_key_set_key_sha(sym_key, env, encrypted_key_hash);
    AXIS2_FREE(env->allocator, decoded_enc_sec);

    /*Free*/
    oxs_buffer_free(result, env);
    result = NULL;

    return AXIS2_SUCCESS;
}

/**
* Inspect the key node. Then populate the sym_key
*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
oxs_xml_enc_decrypt_key(
    const axutil_env_t *env,
    oxs_asym_ctx_t * asym_ctx,
    axiom_node_t *parent,
    axiom_node_t *encrypted_key_node,
    oxs_key_t *key)
{
    axiom_node_t *enc_mtd_node = NULL;
    axiom_node_t *key_info_node = NULL;
    axiom_node_t *cd_node = NULL;
    axis2_char_t *enc_mtd_algo = NULL;
    axis2_char_t *cipher_val = NULL;
    axis2_char_t *new_cipher_val = NULL;
    axis2_status_t status = AXIS2_FAILURE;
    oxs_buffer_t *input_buf = NULL;
    oxs_buffer_t *result_buf = NULL;
    axis2_char_t *key_name = NULL;

    axis2_char_t* encrypted_key_hash = NULL;
    int decoded_len = 0;
    axis2_char_t *decoded_enc_sec = NULL;

    /*Get encryption method algorithm*/
    enc_mtd_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node,
        OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, OXS_XENC);
    enc_mtd_algo = oxs_token_get_encryption_method(env, enc_mtd_node);
    if(!enc_mtd_algo)
    {
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED,
            "Cannot find the Encryption method");
        return AXIS2_FAILURE;
    }
    /*Get cipher data*/
    cd_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node, OXS_NODE_CIPHER_DATA,
        OXS_ENC_NS, OXS_XENC);
    cipher_val = oxs_token_get_cipher_value_from_cipher_data(env, cd_node);
    if(!cipher_val)
    {
        oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED,
            "Cannot find the cipher value for key decryption");
        return AXIS2_FAILURE;
    }

    new_cipher_val = oxs_util_get_newline_removed_string(env, cipher_val);

    /*Get key used to encrypt*/
    key_info_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node,
        OXS_NODE_KEY_INFO, OXS_DSIG_NS, OXS_DS);
    status = oxs_xml_enc_process_key_info(env, asym_ctx, key_info_node, parent);
    /*Right now we support KeyInfo -> SecurityTokenReference -> Reference
     KeyInfo -> SecurityTokenReference -> X509IssuerSerial */

    /*Get the pkey used to decrypt the session key. If found set it to the asym_ctx*/
    /*Create the input buffer*/
    input_buf = oxs_buffer_create(env);
    oxs_buffer_populate(input_buf, env, (unsigned char*)new_cipher_val, axutil_strlen(
        new_cipher_val));

    /*Create a results buffer*/
    result_buf = oxs_buffer_create(env);

    /*Call decryption*/
    status = oxs_encryption_asymmetric_crypt(env, asym_ctx, input_buf, result_buf);
    /*Free input*/
    oxs_buffer_free(input_buf, env);
    input_buf = NULL;

    /*calculate the EncryptedKeySHA1 and set as the key_sha*/
    decoded_len = axutil_base64_decode_len(new_cipher_val);
    decoded_enc_sec = AXIS2_MALLOC(env->allocator, decoded_len);
    axutil_base64_decode_binary((unsigned char*)decoded_enc_sec, new_cipher_val);
    encrypted_key_hash = openssl_sha1(env, decoded_enc_sec, decoded_len);
    AXIS2_FREE(env->allocator, decoded_enc_sec);

    AXIS2_FREE(env->allocator, new_cipher_val);
    new_cipher_val = NULL;

    if(AXIS2_FAILURE == status)
    {
        return AXIS2_FAILURE;
    }

    key_name = oxs_axiom_get_attribute_value_of_node_by_name(env, encrypted_key_node, OXS_ATTR_ID,
        NULL);
    /*Populate the key with the data in the result buffer*/
    oxs_key_populate(key, env, oxs_buffer_get_data(result_buf, env), key_name, oxs_buffer_get_size(
        result_buf, env), OXS_KEY_USAGE_SESSION);
    oxs_key_set_key_sha(key, env, encrypted_key_hash);

    /*Free*/
    oxs_buffer_free(result_buf, env);
    result_buf = NULL;

    return AXIS2_SUCCESS;
}
