| /* |
| * 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; |
| } |
| |
| } |
| |
| |
| |