blob: 14b5ff4407a1cb3372a7cf037cc7a2eae313824b [file] [log] [blame]
/*
* 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 <rampart_encryption.h>
#include <rampart_constants.h>
#include <rampart_sec_header_processor.h>
#include <rampart_username_token.h>
#include <rampart_timestamp_token.h>
#include <rampart_util.h>
#include <rampart_sec_processed_result.h>
#include <rampart_handler_util.h>
#include <oxs_ctx.h>
#include <oxs_error.h>
#include <oxs_utility.h>
#include <oxs_key.h>
#include <oxs_axiom.h>
#include <oxs_asym_ctx.h>
#include <oxs_tokens.h>
#include <axutil_utils.h>
#include <axutil_array_list.h>
#include <axis2_key_type.h>
#include <rampart_token_processor.h>
#include <oxs_sign_ctx.h>
#include <oxs_xml_signature.h>
#include <oxs_key_mgr.h>
/*Private functions*/
static axis2_bool_t
rampart_shp_validate_qnames(const axutil_env_t *env,
axiom_node_t *node)
{
axiom_element_t *node_ele = NULL;
axutil_qname_t *qname = NULL;
axutil_qname_t *node_qname = NULL;
axis2_char_t *local_name = NULL;
AXIS2_ENV_CHECK(env,AXIS2_FALSE);
node_ele = axiom_node_get_data_element(node, env);
if(!node_ele)
return AXIS2_FALSE;
local_name = axiom_element_get_localname(node_ele,env);
if(!local_name){
return AXIS2_FALSE;
}
if(axutil_strcmp(local_name, RAMPART_SECURITY_TIMESTAMP) == 0)
{
qname = axutil_qname_create(env, local_name, RAMPART_WSU_XMLNS, NULL/*RAMPART_WSU*/);
}
else if(axutil_strcmp(local_name, RAMPART_SECURITY_USERNAMETOKEN) ==0)
{
qname = axutil_qname_create(env, local_name, RAMPART_WSSE_XMLNS, NULL/*RAMPART_WSSE*/);
}
else if(axutil_strcmp(local_name,OXS_NODE_ENCRYPTED_KEY)==0)
{
qname = axutil_qname_create(env, local_name, OXS_ENC_NS, NULL/*OXS_XENC*/);
}
else if(axutil_strcmp(local_name, OXS_NODE_ENCRYPTED_DATA)==0)
{
qname = axutil_qname_create(env, local_name, OXS_ENC_NS, NULL/*OXS_XENC*/);
}
else if(axutil_strcmp(local_name, OXS_NODE_SIGNATURE)==0)
{
qname = axutil_qname_create(env, local_name, OXS_DSIG_NS, NULL/*OXS_DS*/);
}
else if(axutil_strcmp(local_name, OXS_NODE_BINARY_SECURITY_TOKEN) == 0)
{
return AXIS2_FALSE;
}
else if(axutil_strcmp(local_name, OXS_NODE_REFERENCE_LIST)==0)
{
return AXIS2_FALSE;
}
else
{
return AXIS2_FALSE;
}
if(!qname)
{
return AXIS2_FALSE;
}
node_qname = axiom_element_get_qname(node_ele, env, node);
if(!node_qname)
{
axutil_qname_free(qname, env);
qname = NULL;
return AXIS2_FALSE;
}
if(axutil_qname_equals(qname, env, node_qname))
{
axutil_qname_free(qname, env);
qname = NULL;
return AXIS2_TRUE;
}
return AXIS2_FALSE;
}
static oxs_x509_cert_t *get_receiver_x509_cert(
const axutil_env_t *env,
rampart_context_t *rampart_context)
{
axis2_char_t *file_name = NULL;
axis2_char_t *pem_buf = NULL;
pem_buf = (axis2_char_t *)rampart_context_get_receiver_certificate(
rampart_context, env);
if(pem_buf)
{
return oxs_key_mgr_load_x509_cert_from_string(env, pem_buf);
}
else
{
file_name = rampart_context_get_receiver_certificate_file(rampart_context, env);
if(!file_name)
{
return NULL;
}
else
{
return oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name);
}
}
}
static axis2_status_t
rampart_shp_process_timestamptoken(const axutil_env_t *env,
axis2_msg_ctx_t *msg_ctx,
rampart_context_t *rampart_context,
axiom_node_t *sec_node)
{
axis2_status_t valid_ts = AXIS2_FAILURE;
axiom_node_t *ts_node = NULL;
ts_node = oxs_axiom_get_node_by_local_name(env,
sec_node, RAMPART_SECURITY_TIMESTAMP);
if(!ts_node)
{
if(rampart_context_is_include_timestamp(rampart_context, env))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Timestamp is not in the message");
rampart_create_fault_envelope(env, RAMPART_FAULT_SECURITY_TOKEN_UNAVAILABLE,
"Timestamp is not in the message ", RAMPART_FAULT_IN_TIMESTAMP, msg_ctx);
return AXIS2_FAILURE;
}
else
{
return AXIS2_SUCCESS;
}
}
else if(!rampart_context_is_include_timestamp(rampart_context, env))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Timestamp should not be in the message.");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY_TOKEN,
"Timestamp should not be in the message ", RAMPART_FAULT_IN_TIMESTAMP, msg_ctx);
return AXIS2_FAILURE;
}
else
{
if(!rampart_shp_validate_qnames(env, ts_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in the Timestamp element.");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY_TOKEN,
"Error in the Timestamp Element. ", RAMPART_FAULT_IN_TIMESTAMP, msg_ctx);
return AXIS2_FAILURE;
}
valid_ts = rampart_timestamp_token_validate(env, msg_ctx, ts_node);
if (valid_ts)
{
AXIS2_LOG_INFO(env->log, "[rampart][scp] Succesfully validated the timestamp ");
return AXIS2_SUCCESS;
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][scp] Timestamp is not valid");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Timestamp is not valid", RAMPART_FAULT_IN_TIMESTAMP, msg_ctx);
return AXIS2_FAILURE;
}
}
}
static axis2_status_t
rampart_shp_process_usernametoken(const axutil_env_t *env,
axis2_msg_ctx_t *msg_ctx,
rampart_context_t *rampart_context,
axiom_node_t *sec_node)
{
axis2_status_t valid_user = AXIS2_FAILURE;
axiom_node_t *ut_node = NULL;
ut_node = oxs_axiom_get_node_by_local_name(
env, sec_node, RAMPART_SECURITY_USERNAMETOKEN);
if(!ut_node)
{
if(rampart_context_is_include_username_token(rampart_context, env))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Username token is not in the message");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_AUTHENTICATION,
"Username Token not found", RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);
return AXIS2_FAILURE;
}
else
{
return AXIS2_SUCCESS;
}
}
else if(!rampart_context_is_include_username_token(rampart_context, env))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Username token should not be in the message.");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY_TOKEN,
"Username Token not expected", RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);
return AXIS2_FAILURE;
}
else
{
if(!rampart_shp_validate_qnames(env, ut_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in validating qnames for the username token");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY_TOKEN,
"Error in the Username token.", RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);
return AXIS2_FAILURE;
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Validating UsernameToken");
valid_user = rampart_username_token_validate(env,
msg_ctx, ut_node, rampart_context);
}
if (valid_user)
{
AXIS2_LOG_INFO(env->log, "[rampart][shp] Validating UsernameToken SUCCESS");
return AXIS2_SUCCESS;
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Validating UsernameToken FAILED");
if(!axis2_msg_ctx_get_fault_soap_envelope(msg_ctx, env))
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_AUTHENTICATION,
"UsernameToken validation failed.", RAMPART_FAULT_IN_USERNAMETOKEN, msg_ctx);
}
return AXIS2_FAILURE;
}
}
static axis2_status_t
rampart_shp_process_encrypted_key(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,
axiom_node_t *encrypted_key_node)
{
axiom_node_t *ref_list_node = NULL;
axiom_node_t *enc_mtd_node = NULL;
axutil_array_list_t *reference_list = NULL;
axis2_char_t *enc_asym_algo = NULL;
axis2_char_t *prv_key_file = NULL;
axis2_char_t *password = NULL;
axis2_char_t *enc_user = NULL;
rampart_callback_t *password_callback = NULL;
axis2_status_t status = AXIS2_FAILURE;
oxs_asym_ctx_t *asym_ctx = NULL;
oxs_key_t *decrypted_sym_key = NULL;
axis2_char_t *enc_asym_algo_in_pol = NULL;
axis2_char_t *enc_sym_algo_in_pol = NULL;
password_callback_fn password_function = NULL;
void *param = NULL;
int i = 0;
void *key_buf = NULL;
/*Get EncryptedData references */
ref_list_node = oxs_axiom_get_first_child_node_by_name(
env, encrypted_key_node, OXS_NODE_REFERENCE_LIST, OXS_ENC_NS, NULL);
reference_list = oxs_token_get_reference_list_data(env, ref_list_node);
/*If there are no references. Nothing to do. Return success*/
if((!reference_list) || (0 == axutil_array_list_size(reference_list, env)))
{
AXIS2_LOG_INFO(env->log, "[rampart][shp] Reference List is empty");
return AXIS2_SUCCESS;
}
AXIS2_LOG_INFO(env->log,
"[rampart][shp] Reference List has %d node reference(s)",
axutil_array_list_size(reference_list, env));
/*Get the algorithm to decrypt the sesison key*/
enc_mtd_node = oxs_axiom_get_first_child_node_by_name(
env, encrypted_key_node, OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, NULL);
enc_asym_algo = oxs_token_get_encryption_method(env, enc_mtd_node);
/*If the reference list > 0 then We have nodes to decrypt. Next step is to get the encrypted key*/
/*Obtain the session key which is encrypted*/
/*Create an asym_ctx*/
/*We should verify the algorithm with policy*/
enc_asym_algo_in_pol = rampart_context_get_enc_asym_algo(rampart_context, env);
if(!enc_asym_algo_in_pol)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the policy. No asym algo", RAMPART_FAULT_IN_POLICY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Assymetric enc algorithm not specified in policy.");
return AXIS2_FAILURE;
}
if(axutil_strcmp(enc_asym_algo_in_pol, enc_asym_algo) != 0)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"The key is encrypted with the wrong algorithm");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"The key is encrypted with the wrong algorithm", RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
return AXIS2_FAILURE;
}
asym_ctx = oxs_asym_ctx_create(env);
oxs_asym_ctx_set_algorithm(asym_ctx, env, enc_asym_algo);
key_buf = rampart_context_get_prv_key(rampart_context, env);
if(key_buf)
{
axis2_key_type_t type = 0;
type = rampart_context_get_prv_key_type(rampart_context, env);
if(type == AXIS2_KEY_TYPE_PEM)
{
oxs_asym_ctx_set_pem_buf(asym_ctx, env, (axis2_char_t *)key_buf);
oxs_asym_ctx_set_format(asym_ctx, env, OXS_ASYM_CTX_FORMAT_PEM);
}
}
else
{
prv_key_file = rampart_context_get_private_key_file(rampart_context, env);
if(!prv_key_file)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the policy. No private key", RAMPART_FAULT_IN_POLICY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Private Key is not specified.");
return AXIS2_FAILURE;
}
oxs_asym_ctx_set_file_name(asym_ctx, env, prv_key_file);
oxs_asym_ctx_set_format(asym_ctx, env,
oxs_util_get_format_by_file_extension(env, prv_key_file));
/*Get the password to retrieve the key from key store*/
/* password = rampart_callback_encuser_password(env, actions, msg_ctx);*/
password = rampart_context_get_prv_key_password(rampart_context, env);
if(!password)
{
enc_user = rampart_context_get_encryption_user(rampart_context, env);
if(!enc_user)
{
enc_user = rampart_context_get_user(rampart_context, env);
}
if(enc_user)
{
password_function = rampart_context_get_pwcb_function(rampart_context, env);
if(password_function)
{
password = (*password_function)(env, enc_user, param);
}
else
{
password_callback = rampart_context_get_password_callback(rampart_context, env);
if(!password_callback)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the policy. No password callback", RAMPART_FAULT_IN_POLICY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Password call back module is not specified.");
return AXIS2_FAILURE;
}
password = rampart_callback_password(env, password_callback, enc_user);
}
}
}
oxs_asym_ctx_set_password(asym_ctx, env, password);
}
oxs_asym_ctx_set_operation(asym_ctx, env, OXS_ASYM_CTX_OPERATION_PRV_DECRYPT);
/*oxs_asym_ctx_set_format(asym_ctx, env, OXS_ASYM_CTX_FORMAT_PKCS12);*/
/*Create an empty key*/
decrypted_sym_key = oxs_key_create(env);
/*Call decrypt for the EncryptedKey*/
status = oxs_xml_enc_decrypt_key(env, asym_ctx,
sec_node, encrypted_key_node, decrypted_sym_key);
if(AXIS2_FAILURE == status)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Cannot decrypt the EncryptedKey");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Key decryption failed", RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
return AXIS2_FAILURE;
}
/*Alright now we have the key used to encrypt the elements in the reference_list*/
/*Go thru each and every node in the list and decrypt them*/
/*Before decrypt we should get the symmetric algo from policy.
So for each encrypted element we can compare the algo. */
enc_sym_algo_in_pol = rampart_context_get_enc_sym_algo(rampart_context, env);
if(!enc_sym_algo_in_pol)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the policy. No summetric algo", RAMPART_FAULT_IN_POLICY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Symetric enc algorithm not specified in policy.");
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
return AXIS2_FAILURE;
}
for(i=0 ; i < axutil_array_list_size(reference_list, env); i++ )
{
axis2_char_t *id = NULL;
axis2_char_t *id2 = NULL;
axiom_node_t *enc_data_node = NULL;
axiom_node_t *envelope_node = NULL;
oxs_ctx_t *ctx = NULL;
axiom_node_t *decrypted_node = NULL;
axiom_node_t *mtd_node = NULL;
axis2_char_t *sym_algo = NULL;
axiom_soap_body_t *soap_body = NULL;
/*This need to be done in order to build the soap body.Do not remove.*/
soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
/*Get the i-th element and decrypt it */
id = (axis2_char_t*)axutil_array_list_get(reference_list, env, i);
AXIS2_LOG_INFO(env->log, "[rampart][shp] Decrypting node, ID=%s", id);
/*Need to remove # sign from the ID*/
id2 = axutil_string_substring_starting_at(id, 1);
envelope_node = axiom_soap_envelope_get_base_node(soap_envelope, env);
/*Search for the node by its ID*/
enc_data_node = oxs_axiom_get_node_by_id(env, envelope_node, OXS_ATTR_ID, id2, NULL);
if(!enc_data_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Node with ID=%s cannot be found", id);
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Cannot find EncryptedData element", RAMPART_FAULT_IN_ENCRYPTED_DATA, msg_ctx);
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
return AXIS2_FAILURE;
}
/*Create an enc_ctx*/
mtd_node = oxs_axiom_get_first_child_node_by_name(
env, enc_data_node, OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, NULL);
if(!mtd_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"Cannot find EncryptionMethod Element");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Cannot find EncryptionMethod Element", RAMPART_FAULT_IN_ENCRYPTED_DATA, msg_ctx);
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
return AXIS2_FAILURE;
}
sym_algo = oxs_token_get_encryption_method(env, mtd_node);
if(!sym_algo)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"Cannot get the Symmetric Algorithm from Soap message.");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Cannot find EncryptionMethod Element", RAMPART_FAULT_IN_ENCRYPTED_DATA, msg_ctx);
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
return AXIS2_FAILURE;
}
if(axutil_strcmp(sym_algo, enc_sym_algo_in_pol)!=0)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"The content is encrypted with the wrong algorithm");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"The content is encrypted with the wrong algorithm",
RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
return AXIS2_FAILURE;
}
ctx = oxs_ctx_create(env);
oxs_ctx_set_key(ctx, env, decrypted_sym_key);
status = oxs_xml_enc_decrypt_node(env, ctx, enc_data_node, &decrypted_node);
if(AXIS2_FAILURE == status)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Data decryption failed", RAMPART_FAULT_IN_ENCRYPTED_DATA, msg_ctx);
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
return AXIS2_FAILURE;
}
/*Free*/
oxs_ctx_free(ctx, env);
ctx = NULL;
/*AXIS2_FREE(env->allocator, id);
id = NULL;
*/
AXIS2_LOG_INFO(env->log, "[rampart][shp] Node ID=%s decrypted successfuly", id);
}/*end of For loop*/
/*Set the security processed result*/
rampart_set_security_processed_result(
env, msg_ctx, RAMPART_SPR_ENC_CHECKED, RAMPART_YES);
/*Free*/
oxs_asym_ctx_free(asym_ctx, env);
asym_ctx = NULL;
if(decrypted_sym_key)
{
oxs_key_free(decrypted_sym_key, env);
decrypted_sym_key = NULL;
}
axutil_array_list_free(reference_list, env);
reference_list = NULL;
return AXIS2_SUCCESS;
}
static axis2_status_t
rampart_shp_process_reference_list(
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,
axiom_node_t *ref_list_node)
{
axutil_array_list_t *reference_list = NULL;
axis2_status_t status = AXIS2_FAILURE;
int i = 0;
reference_list = oxs_token_get_reference_list_data(env,
ref_list_node);
if((!reference_list) || (0 == axutil_array_list_size(reference_list, env)))
{
if (reference_list)
{
axutil_array_list_free(reference_list, env);
reference_list = NULL;
}
AXIS2_LOG_INFO(env->log,
"[rampart][shp] Nothing Encrypted Outside security header");
return AXIS2_SUCCESS;
}
for(i=0 ; i < axutil_array_list_size(reference_list, env); i++ )
{
axis2_char_t *id = NULL;
axis2_char_t *id2 = NULL;
axiom_node_t *enc_data_node = NULL;
axiom_node_t *envelope_node = NULL;
axiom_soap_body_t *soap_body = NULL;
axiom_node_t *key_info_node = NULL;
axiom_node_t *str_node = NULL;
soap_body = axiom_soap_envelope_get_body(soap_envelope, env);
id = (axis2_char_t*)axutil_array_list_get(reference_list, env, i);
id2 = axutil_string_substring_starting_at(axutil_strdup(env, id), 1);
envelope_node = axiom_soap_envelope_get_base_node(soap_envelope, env);
/*Search for the node by its ID*/
enc_data_node = oxs_axiom_get_node_by_id(env, envelope_node, OXS_ATTR_ID, id2, NULL);
if(!enc_data_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Node with ID=%s cannot be found", id2);
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Cannot find EncryptedData element", RAMPART_FAULT_IN_ENCRYPTED_DATA, msg_ctx);
axutil_array_list_free(reference_list, env);
reference_list = NULL;
AXIS2_FREE(env->allocator, id2);
id2 = NULL;
return AXIS2_FAILURE;
}
AXIS2_FREE(env->allocator, id2);
id2 = NULL;
key_info_node = oxs_axiom_get_first_child_node_by_name(env, enc_data_node,
OXS_NODE_KEY_INFO, OXS_DSIG_NS, NULL);
if(key_info_node)
{
str_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,
OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL);
if(str_node)
{
axiom_node_t *str_child_node = NULL;
axis2_char_t *str_child_name = NULL;
str_child_node = axiom_node_get_first_element(str_node, env);
str_child_name = axiom_util_get_localname(str_child_node, env);
if(str_child_name)
{
if(axutil_strcmp(str_child_name, OXS_NODE_REFERENCE) == 0)
{
axis2_char_t *ref = NULL;
axis2_char_t *ref_id = NULL;
axiom_node_t *encrypted_key_node = NULL;
ref = oxs_token_get_reference(env, str_child_node);
ref_id = axutil_string_substring_starting_at(axutil_strdup(env, ref), 1);
encrypted_key_node = oxs_axiom_get_node_by_id(env, sec_node, "Id", ref_id, NULL);
AXIS2_FREE(env->allocator, ref_id);
ref_id = NULL;
if(encrypted_key_node)
{
ref_list_node = axiom_node_detach(ref_list_node, env);
axiom_node_add_child(encrypted_key_node, env, ref_list_node);
status = rampart_shp_process_encrypted_key(env, msg_ctx, rampart_context,
soap_envelope, sec_node, encrypted_key_node);
break;
}
}
}
}
}
}
axutil_array_list_free(reference_list, env);
reference_list = NULL;
return status;
}
static axis2_status_t
rampart_shp_process_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,
axiom_node_t *sig_node)
{
oxs_sign_ctx_t *sign_ctx = NULL;
axis2_status_t status = AXIS2_FAILURE;
axis2_char_t *digest_mtd_pol = NULL;
axis2_char_t *sig_mtd_pol = NULL;
axiom_node_t *sign_info_node = NULL;
axiom_node_t *cur_node = NULL;
rp_property_t *token = NULL;
axis2_bool_t server_side = AXIS2_FALSE;
axis2_char_t *eki = NULL;
rp_property_type_t token_type;
axiom_node_t *key_info_node = NULL;
axiom_node_t *str_node = NULL;
axiom_node_t *str_child_node = NULL;
axis2_char_t *str_child_name = NULL;
oxs_x509_cert_t *cert = NULL;
axiom_node_t *key_info_child_node = NULL;
axiom_node_t *envelope_node = NULL;
axis2_bool_t is_include_token = AXIS2_FALSE;
server_side = axis2_msg_ctx_get_server_side(msg_ctx,env);
sig_mtd_pol = rampart_context_get_asym_sig_algo(rampart_context,env);
digest_mtd_pol = rampart_context_get_digest_mtd(rampart_context,env);
if(!sig_mtd_pol || !digest_mtd_pol)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the policy. No signature algo", RAMPART_FAULT_IN_POLICY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in policy, Specifying signature algorithms.");
return AXIS2_FAILURE;
}
sign_info_node = oxs_axiom_get_first_child_node_by_name(env, sig_node,
OXS_NODE_SIGNEDINFO, OXS_DSIG_NS, NULL);
if(!sign_info_node)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Sign info node not found.", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Sign info cannot be found.Verifycation failed");
return AXIS2_FAILURE;
}
cur_node = axiom_node_get_first_element(sign_info_node, env);
while(cur_node)
{
axis2_char_t *localname = NULL;
localname = axiom_util_get_localname(cur_node, env);
if(axutil_strcmp(localname, OXS_NODE_SIGNATURE_METHOD)==0)
{
/*Verify the signature method with policy*/
axis2_char_t *sig_mtd = NULL;
sig_mtd = oxs_token_get_signature_method(env, cur_node);
if(sig_mtd)
{
if(axutil_strcmp(sig_mtd_pol, sig_mtd)!=0)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Signed with Invalid algorithm", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Signed with Invalid algorithm");
return AXIS2_FAILURE;
}
}
else
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Signature method element not found .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Signature method element not found");
return AXIS2_FAILURE;
}
}
else if(axutil_strcmp(localname, OXS_NODE_REFERENCE)==0)
{
/*Verify each digest method with policy*/
axiom_node_t *digest_mtd_node = NULL;
axis2_char_t *digest_mtd = NULL;
digest_mtd_node = oxs_axiom_get_first_child_node_by_name(env, cur_node,
OXS_NODE_DIGEST_METHOD, OXS_DSIG_NS, NULL);
if(digest_mtd_node)
{
digest_mtd = oxs_token_get_digest_method(env, digest_mtd_node);
if(digest_mtd)
{
if(axutil_strcmp(digest_mtd_pol, digest_mtd)!=0)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Digest created with Invalid algorithm", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Digest Created with Invalid algorithm");
return AXIS2_FAILURE;
}
}
else
{
return AXIS2_FAILURE;
}
}
else
{
return AXIS2_FAILURE;
}
}
else
{
/*we do not need to process at this moment*/
}
cur_node = axiom_node_get_next_sibling(cur_node, env);
}
/*Get the key identifiers and build the certificate*/
/*First we should verify with policy*/
token = rampart_context_get_token(rampart_context, env,
AXIS2_FALSE, server_side, AXIS2_TRUE);
if(!token)
{
AXIS2_LOG_INFO(env->log,
"[rampart][shp] Signature Token is not specified");
return AXIS2_SUCCESS;
}
token_type = rp_property_get_type(token, env);
if(!rampart_context_is_token_type_supported(token_type, env))
{
rampart_create_fault_envelope(env, RAMPART_FAULT_UNSUPPORTED_SECURITY_TOKEN,
"The token type does not supported", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] The token type does not supported");
return AXIS2_FAILURE;
}
if(rampart_context_check_is_derived_keys(env, token))
{
rampart_create_fault_envelope(env, RAMPART_FAULT_UNSUPPORTED_SECURITY_TOKEN,
"Derived Keys are not supported.", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Derived Keys are not supported.");
return AXIS2_FAILURE;
}
is_include_token = rampart_context_is_token_include(
rampart_context, token, token_type, server_side, AXIS2_TRUE, env);
key_info_node = oxs_axiom_get_first_child_node_by_name(env, sig_node,
OXS_NODE_KEY_INFO, OXS_DSIG_NS, NULL );
if(!key_info_node)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Key Info node is not in the message .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp]Verify failed. Key Info node is not in the message.");
return AXIS2_FAILURE;
}
str_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,
OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL);
if(str_node)
{
str_child_node = axiom_node_get_first_element(str_node,env);
if(str_child_node)
{
str_child_name = axiom_util_get_localname(str_child_node, env);
if(str_child_name)
{
if(is_include_token)
{
if(axutil_strcmp(str_child_name, OXS_NODE_REFERENCE)!=0)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Token is not in the message .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Token is not included in the message ");
return AXIS2_FAILURE;
}
cert = oxs_x509_cert_create(env);
status = rampart_token_process_direct_ref(env, str_child_node, sec_node, cert);
}
else
{
if(0 == axutil_strcmp(str_child_name, OXS_NODE_EMBEDDED))
{
if(!rampart_context_is_key_identifier_type_supported(
rampart_context, token, RAMPART_STR_EMBEDDED, env))
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Key Reference Type not supported .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Key Reference Info mismatch (%s, %s)", str_child_name, OXS_NODE_EMBEDDED);
return AXIS2_FAILURE;
}
cert = oxs_x509_cert_create(env);
status = rampart_token_process_embedded(env, str_child_node, cert);
}
else if(0 == axutil_strcmp(str_child_name, OXS_NODE_KEY_IDENTIFIER))
{
if(!rampart_context_is_key_identifier_type_supported(
rampart_context, token, RAMPART_STR_KEY_IDENTIFIER, env))
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Key Reference Type not supported .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Key Reference Info mismatch (%s, %s)", str_child_name, OXS_NODE_KEY_IDENTIFIER);
return AXIS2_FAILURE;
}
cert = get_receiver_x509_cert(env, rampart_context);
status = AXIS2_SUCCESS;
}
else if(0 == axutil_strcmp(str_child_name, OXS_NODE_X509_DATA))
{
if(!rampart_context_is_key_identifier_type_supported(
rampart_context, token, RAMPART_STR_ISSUER_SERIAL, env))
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Key Reference Type not supported .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Key Reference Info mismatch (%s, %s)", str_child_name, OXS_NODE_X509_DATA);
return AXIS2_FAILURE;
}
cert = get_receiver_x509_cert(env,rampart_context);
status = AXIS2_SUCCESS;
}
else
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Key Reference Type not supported .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI ,
"[Rampart][shp]Key Reference %s not supported ", str_child_name);
return AXIS2_FAILURE;
}
}
if(status != AXIS2_SUCCESS || !cert)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY_TOKEN,
"Cannot load the key to verify the message .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI ,
"[Rampart][shp] Cannot load the key to verify the message");
return AXIS2_FAILURE;
}
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Cannot get the key Reference Type from the message.");
return AXIS2_FAILURE;
}
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]No Child node in the Security Token Reference Element.");
return AXIS2_FAILURE;
}
}
/*So there may be scenarios where there is no Security Token Reference Element.*/
else
{
/*In such case policy support only Isssuer Serial scenario.*/
if(axutil_strcmp(eki, RAMPART_STR_ISSUER_SERIAL)==0)
{
key_info_child_node = axiom_node_get_first_element(key_info_node, env);
if(key_info_child_node)
{
axis2_char_t *key_info_child_name = NULL;
key_info_child_name = axiom_util_get_localname(key_info_child_node, env);
if(key_info_child_name)
{
if(0 == axutil_strcmp(key_info_child_name, OXS_NODE_X509_DATA))
{
status = rampart_token_process_x509_data(env, key_info_child_node, cert);
if(status != AXIS2_SUCCESS || !cert)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY_TOKEN,
"Cannot load the key to verify the message .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI ,
"[Rampart][shp] Cannot load the key to verify the message");
return AXIS2_FAILURE;
}
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Cannot get the key Reference Type from the message.");
return AXIS2_FAILURE;
}
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Cannot get the key Reference Type from the message.");
return AXIS2_FAILURE;
}
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Cannot get the key Reference Type from the message.");
return AXIS2_FAILURE;
}
}
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Can't be used as a direct child of Key Info");
return AXIS2_FAILURE;
}
}
sign_ctx = oxs_sign_ctx_create(env);
if(!sign_ctx)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Sign context creation failed. Out of Memeory.");
return AXIS2_FAILURE;
}
/*Set the required values in sig_ctx*/
oxs_sign_ctx_set_operation(sign_ctx, env, OXS_SIGN_OPERATION_VERIFY);
oxs_sign_ctx_set_certificate(sign_ctx, env, cert);
envelope_node = axiom_soap_envelope_get_base_node(soap_envelope, env);
if(!envelope_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Cannot get the Envelope node from envelope.");
return AXIS2_FAILURE;
}
/*Verify the signature*/
status = oxs_xml_sig_verify(env, sign_ctx, sig_node,envelope_node);
if(status != AXIS2_SUCCESS)
{
if(!axis2_msg_ctx_get_fault_soap_envelope(msg_ctx, env))
{
rampart_create_fault_envelope(
env, RAMPART_FAULT_INVALID_SECURITY,
"Signature Verification failed.", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
}
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[Rampart][shp]Signature Verification failed.");
return AXIS2_FAILURE;
}
if(sign_ctx)
{
oxs_sign_ctx_free(sign_ctx, env);
sign_ctx = NULL;
}
return status;
}
/*Public functions*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_shp_process_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)
{
axiom_node_t *cur_node = NULL;
axis2_status_t status = AXIS2_FAILURE;
axis2_bool_t need_replay_detection = AXIS2_FALSE;
axis2_bool_t signature_protection = AXIS2_FALSE;
AXIS2_LOG_INFO(env->log, "[rampart][shp] Processing security header");
if((rampart_context_get_binding_type(rampart_context, env)) ==
RP_PROPERTY_ASYMMETRIC_BINDING)
{
signature_protection = rampart_context_is_encrypt_signature(
rampart_context, env);
if(rampart_context_is_encrypt_before_sign(rampart_context, env))
{
if(signature_protection)
{
axiom_node_t *ref_list_node = NULL;
cur_node = oxs_axiom_get_node_by_local_name(
env, sec_node, OXS_NODE_ENCRYPTED_KEY);
if(!cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] No Encrypted Key element.");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Signature is not encrypted.", RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
return AXIS2_FAILURE;
}
if(!rampart_shp_validate_qnames(env, cur_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in the Encrypted key element");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the Encrypted key element ", RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
return AXIS2_FAILURE;
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Process EncryptedKey");
status = rampart_shp_process_encrypted_key(
env, msg_ctx, rampart_context, soap_envelope, sec_node, cur_node);
if(status != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Encrypted key processing failed.");
return status;
}
ref_list_node = oxs_axiom_get_first_child_node_by_name(
env, cur_node, OXS_NODE_REFERENCE_LIST, OXS_ENC_NS, NULL);
axiom_node_detach(ref_list_node, env);
axiom_node_free_tree(ref_list_node, env);
ref_list_node = NULL;
}
/*First we should verify signature.*/
if(rampart_context_check_whether_to_sign(rampart_context, env))
{
cur_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_SIGNATURE);
if(!cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] No Signature element");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Message is not signed ", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
return AXIS2_FAILURE;
}
if(!rampart_shp_validate_qnames(env, cur_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in the Signature element");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the Signature element ", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
return AXIS2_FAILURE;
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Processing Signature element.");
status = rampart_shp_process_signature(
env, msg_ctx, rampart_context, soap_envelope, sec_node, cur_node);
if(status != AXIS2_SUCCESS)
{
if(!axis2_msg_ctx_get_fault_soap_envelope(msg_ctx, env))
{
rampart_create_fault_envelope(
env, RAMPART_FAULT_INVALID_SECURITY, "Signature is not valid", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
return status;
}
else
{
return status;
}
}
}
else
{
cur_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_SIGNATURE);
if(cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] policy does not specify signature");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Policy does not specify signature ", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
return AXIS2_FAILURE;
}
else
{
status = AXIS2_SUCCESS;
}
}
/*This verification is a quick hack.This should be cganged in the future
with a proper verification method before message processing
Because we need to compare the protected nodes in the message
with the nodes to protect in policy. */
if(rampart_context_check_whether_to_encrypt(rampart_context, env))
{
if(!signature_protection)
{
cur_node = oxs_axiom_get_node_by_local_name(
env, sec_node, OXS_NODE_ENCRYPTED_KEY);
if(!cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] No Encrypted Key element.");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Signature is not encrypted.", RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
return AXIS2_FAILURE;
}
if(!rampart_shp_validate_qnames(env, cur_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in the Encrypted key element");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the Encrypted key element ", RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
return AXIS2_FAILURE;
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Process EncryptedKey");
status = rampart_shp_process_encrypted_key(
env, msg_ctx, rampart_context, soap_envelope, sec_node, cur_node);
if(status != AXIS2_SUCCESS)
{
if(!axis2_msg_ctx_get_fault_soap_envelope(msg_ctx, env))
{
rampart_create_fault_envelope(
env, RAMPART_FAULT_INVALID_SECURITY, "Encryption key processing failed.",
RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
}
return status;
}
}
else
{
cur_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_REFERENCE_LIST);
if(!cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Protection order is wrong or Signature not encrypted.");
rampart_create_fault_envelope(
env, RAMPART_FAULT_INVALID_SECURITY, "Protection order is wrong or Signature is not encrypted. ",
RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
return AXIS2_FAILURE;
}
status = rampart_shp_process_reference_list(env, msg_ctx,
rampart_context, soap_envelope, sec_node, cur_node);
if(status != AXIS2_SUCCESS)
{
rampart_create_fault_envelope(
env, RAMPART_FAULT_INVALID_SECURITY, "Error in decrypting the signature. ",
RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in decrypting the Signature.");
return status;
}
}
}
else
{
cur_node = oxs_axiom_get_node_by_local_name(
env, sec_node, OXS_NODE_ENCRYPTED_KEY);
if(cur_node)
{
AXIS2_LOG_INFO(env->log, "[rampart][shp] policy does not specify encryption.");
return AXIS2_FAILURE;
}
else
status = AXIS2_SUCCESS;
}
}
else
{
/*We should decrypt the message first*/
if(rampart_context_check_whether_to_encrypt(rampart_context,env))
{
cur_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_ENCRYPTED_KEY);
if(!cur_node)
{
AXIS2_LOG_INFO(env->log, "[rampart][shp] No Encrypted Key element");
return AXIS2_FAILURE;
}
if(!rampart_shp_validate_qnames(env,cur_node))
{
AXIS2_LOG_INFO(env->log, "[rampart][shp] Error in the security header");
return AXIS2_FAILURE;
}
if(signature_protection)
{
if(oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_SIGNATURE))
{
AXIS2_LOG_INFO(env->log, "[rampart][shp] Signature is not Encrypted.");
return AXIS2_FAILURE;
}
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Process EncryptedKey");
status = rampart_shp_process_encrypted_key(env,msg_ctx, rampart_context, soap_envelope, sec_node, cur_node);
if(status!=AXIS2_SUCCESS)
return status;
}
else
{
cur_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_ENCRYPTED_KEY);
if(cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] policy does not specify Encryption");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Policy does not specify Encryption. ", RAMPART_FAULT_IN_ENCRYPTED_KEY, msg_ctx);
}
else
{
status = AXIS2_SUCCESS;;
}
}
/*After decrypting we may verify signature stuff.*/
if(rampart_context_check_whether_to_sign(rampart_context, env))
{
cur_node = oxs_axiom_get_node_by_local_name(env, sec_node, OXS_NODE_SIGNATURE);
if(!cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] No Signature element");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Message is not signed ", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
return AXIS2_FAILURE;
}
if(!rampart_shp_validate_qnames(env, cur_node))
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Error in the Signature element");
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Error in the Signature element ", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
return AXIS2_FAILURE;
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Processing Signature element.");
status = rampart_shp_process_signature(env, msg_ctx,
rampart_context, soap_envelope, sec_node, cur_node);
if(status != AXIS2_SUCCESS)
{
if(!axis2_msg_ctx_get_fault_soap_envelope(msg_ctx, env))
{
rampart_create_fault_envelope(
env, RAMPART_FAULT_INVALID_SECURITY, "Signature is not valid",
RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
return status;
}
else
{
return status;
}
}
}
else
{
cur_node = oxs_axiom_get_node_by_local_name(env, sec_node,OXS_NODE_SIGNATURE);
if(cur_node)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] policy does not specify signature");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY,
"Policy does not specify signature ", RAMPART_FAULT_IN_SIGNATURE, msg_ctx);
}
else
{
status = AXIS2_SUCCESS;
}
}
}
/*Now we can process timestamp*/
status = rampart_shp_process_timestamptoken(
env, msg_ctx, rampart_context, sec_node);
if(status != AXIS2_SUCCESS)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Timestamp Processing failed.");
return status;
}
if(axis2_msg_ctx_get_server_side(msg_ctx, env))
{
status = rampart_shp_process_usernametoken(
env, msg_ctx, rampart_context, sec_node);
if(status != AXIS2_SUCCESS)
{
return status;
}
}
if(NULL == rampart_context_get_rd_val(rampart_context, env)){
AXIS2_LOG_INFO(env->log, "[rampart][shp] Replay detection is not specified. Nothing to do");
need_replay_detection = AXIS2_FALSE;
}else{
AXIS2_LOG_INFO(env->log, "[rampart][shp] Checking message for replay.");
need_replay_detection = AXIS2_TRUE;
}
if(AXIS2_TRUE == need_replay_detection){/*TODO Chk for the policy configuration*/
rampart_is_replayed_fn rd_fn = NULL;
/*Is replayed*/
rd_fn = rampart_context_get_replay_detect_function(rampart_context, env);
if(rd_fn){
status = (*rd_fn)(env, msg_ctx, rampart_context);
if(status != AXIS2_SUCCESS){
/*Scream .. replayed*/
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,"[rampart][shp] Message can be replayed");
rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY, "Message is replayed", RAMPART_FAULT_MSG_REPLAYED, msg_ctx);
return AXIS2_FAILURE;
}else{
AXIS2_LOG_INFO(env->log, "[rampart][shp] Checked message for replays. Not a replay.");
}
}else{
AXIS2_LOG_INFO(env->log, "[rampart][shp] No replay detection function specified. Nothing to do. ");
}
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Security header element processing, DONE ");
/*Do the action accordingly*/
return AXIS2_SUCCESS;
}
else if((rampart_context_get_binding_type(rampart_context, env))
== RP_PROPERTY_SYMMETRIC_BINDING)
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Symmetric binding is not supported.", RAMPART_FAULT_IN_POLICY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"Symmetric binding is not supported");
return AXIS2_FAILURE;
}
else if((rampart_context_get_binding_type(rampart_context, env)) ==
RP_PROPERTY_TRANSPORT_BINDING)
{
axis2_status_t status = AXIS2_FAILURE;
status = rampart_shp_process_timestamptoken(
env, msg_ctx, rampart_context, sec_node);
if(status != AXIS2_SUCCESS)
{
return status;
}
if( axis2_msg_ctx_get_server_side(msg_ctx, env))
{
status = rampart_shp_process_usernametoken(
env, msg_ctx, rampart_context, sec_node);
if(status!=AXIS2_SUCCESS)
{
return status;
}
}
if(AXIS2_TRUE == need_replay_detection){/*TODO Chk for the policy configuration*/
rampart_is_replayed_fn rd_fn = NULL;
/*Is replayed*/
rd_fn = rampart_context_get_replay_detect_function(rampart_context, env);
if(rd_fn){
status = (*rd_fn)(env, msg_ctx, rampart_context);
if(status != AXIS2_SUCCESS){
/*Scream .. replayed*/
return AXIS2_FAILURE;
}else{
AXIS2_LOG_INFO(env->log, "[rampart][shp] Checked message for replays. Not a replay.");
}
}else{
AXIS2_LOG_INFO(env->log, "[rampart][shp] No replay detection function specified. Nothing to do. ");
}
}
AXIS2_LOG_INFO(env->log, "[rampart][shp] Security header element processing, DONE ");
/*Do the action accordingly*/
return AXIS2_SUCCESS;
}
else
{
rampart_create_fault_envelope(env, RAMPART_FAULT_FAILED_CHECK,
"Unsupportive binding type.", RAMPART_FAULT_IN_POLICY, msg_ctx);
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
"[rampart][shp] Unsupportive binding type.");
return AXIS2_FAILURE;
}
}