Exemplo n.º 1
0
/**
 * Verify that an addressing element is located in <Envelope>/<Header>
 */
int verify_addr_hdr_elem_loc(axiom_node_t *signed_node, const axutil_env_t *env, axis2_char_t *ref) {

    axiom_node_t *parent = axiom_node_get_parent(signed_node,env);

    if(axutil_strcmp(OXS_NODE_HEADER, axiom_util_get_localname(parent, env))) {
       AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] parent of addressing elem is %s", axiom_node_to_string(parent, env));
       oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unexpected location of signed addressing elem with ID = %s", ref);
       return 1;

    }
     parent = axiom_node_get_parent(parent,env);

    if(axutil_strcmp(OXS_NODE_ENVELOPE, axiom_util_get_localname(parent, env))) {
       AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] second parent of addressing elem is %s", axiom_node_to_string(parent, env));
       oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unexpected location of signed addressing elem with ID = %s", ref);
       return 1;

    }

     parent = axiom_node_get_parent(parent,env);
     if(parent) {
       AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] parent of Envelope = %s", axiom_node_to_string(parent, env));
       oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unexpected location of signed Body with ID = %s", ref);
       return 1;
     }

     return 0;
}
Exemplo n.º 2
0
/**
 * Traverse thru the node and its descendents. Check if the localname is equal to the given name
 * @param env Environment. MUST NOT be NULL,
 * @param node the node to be searched
 * @param localname the local name of the node to be searched
 * @return the node if found, else NULL
 */
AXIS2_EXTERN axiom_node_t* AXIS2_CALL
oxs_axiom_get_node_by_local_name(
    const axutil_env_t *env,
    axiom_node_t *node,
    axis2_char_t *local_name)
{
    axis2_char_t *temp_name = NULL;

    if(!node)
    {
        return NULL;
    }

    if(axiom_node_get_node_type(node, env) != AXIOM_ELEMENT)
    {
        return NULL;
    }

    temp_name = axiom_util_get_localname(node, env);
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, 
        "[rampart]Checking node %s for %s", temp_name, local_name );

    if(!axutil_strcmp(temp_name, local_name))
    {
        /* Gottcha.. return this node */
        return node;
    }
    else
    {
        /* Doesn't match? Get the children and search for them */
        axiom_node_t *temp_node = NULL;

        temp_node = axiom_node_get_first_element(node, env);
        while(temp_node)
        {
            axiom_node_t *res_node = NULL;
            res_node = oxs_axiom_get_node_by_local_name(env, temp_node, local_name);
            if(res_node)
            {
                return res_node;
            }
            temp_node = axiom_node_get_next_sibling(temp_node, env);
        }
    }
    return NULL;
}
/**
 * extract certificate related information using given token_reference node and scope node
 * @param env Environment structure
 * @param st_ref_node security token reference node.
 * @param scope_node node where additional details should be found. Can be NULL for all other
 *  scenarios but the Direct Reference
 * @param cert certificate where values extracted shuold be populated
 * @return status of the operation
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_token_process_security_token_reference(
    const axutil_env_t *env,
    axiom_node_t *st_ref_node,
    axiom_node_t *scope_node,
    oxs_x509_cert_t *cert)
{
    axis2_char_t *child_name = NULL;
    axiom_node_t *child_node = NULL;
    axis2_status_t status = AXIS2_FAILURE;

    child_node = axiom_node_get_first_element(st_ref_node, env);
    child_name = axiom_util_get_localname(child_node, env);

    if(!axutil_strcmp(child_name, OXS_NODE_REFERENCE))
    {
        status = rampart_token_process_direct_ref(env, child_node, scope_node, cert);
    }
    else if(!axutil_strcmp(child_name, OXS_NODE_EMBEDDED))
    {
        status = rampart_token_process_embedded(env, child_node, cert);
    }
    else if(!axutil_strcmp(child_name, OXS_NODE_KEY_IDENTIFIER))
    {
        status = rampart_token_process_key_identifier(env, child_node, cert);
    }
    else if(!axutil_strcmp(child_name, OXS_NODE_X509_DATA))
    {
        status = rampart_token_process_x509_data(env, child_node, cert);
    }
    else
    {
        /* reference method is not supported */
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
            "[rampart]%s of wsse:SecurityTokenReference is not supported.", child_name);
        return AXIS2_FAILURE;
    }

    return status;
}
Exemplo n.º 4
0
/**
 * Verifies XPath location of signed elements.
 */ 
int verify_node(axiom_node_t *signed_node, const axutil_env_t *env, axis2_msg_ctx_t *msg_ctx, axis2_char_t *ref, short *signed_elems) {

  if(!axutil_strcmp(OXS_NODE_BODY, axiom_util_get_localname(signed_node, env))) {
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] node %s is Body", ref); 
    signed_elems[0] = 1;

    axiom_node_t *parent = axiom_node_get_parent(signed_node,env);
    if(axutil_strcmp(OXS_NODE_ENVELOPE, axiom_util_get_localname(parent, env))) {
       oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unexpected parent element for Body with ID = %s", ref);
       return 1;
    }

     parent = axiom_node_get_parent(parent,env);
     if(parent) {
       AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] parent of Envelope = %s", axiom_node_to_string(parent, env));
       oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unexpected location of signed Body with ID = %s", ref);
       return 1;
     }

  } else if(!axutil_strcmp(RAMPART_SECURITY_TIMESTAMP, axiom_util_get_localname(signed_node, env))) {
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] node %s is Timestamp", ref); 
    signed_elems[1] = 1;

    /* Regardless of the location of the Timestamp, verify the one that is signed */
    if(AXIS2_FAILURE == rampart_timestamp_token_validate(env, msg_ctx, signed_node, 20)) {
       oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Validation failed for Timestamp with ID = %s", ref);
      return 1;
    }

  } else if(!axutil_strcmp(AXIS2_WSA_ACTION, axiom_util_get_localname(signed_node, env))) {
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] node %s is Action", ref); 
    signed_elems[2] = 1;

    if(verify_addr_hdr_elem_loc(signed_node, env, ref)) {
	oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Validation failed for Action with ID = %s", ref);
	return 1;
      }

  } else if(!axutil_strcmp(AXIS2_WSA_TO, axiom_util_get_localname(signed_node, env))) {
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] node %s is To", ref); 
    signed_elems[3] = 1;
 
    if(verify_addr_hdr_elem_loc(signed_node, env, ref)) {
	oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Validation failed for To with ID = %s", ref);
	return 1;
      }


  } else if(!axutil_strcmp(AXIS2_WSA_MESSAGE_ID, axiom_util_get_localname(signed_node, env))) {
    AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] node %s is MessageId", ref); 
    signed_elems[4] = 1;

    if(verify_addr_hdr_elem_loc(signed_node, env, ref)) {
	oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Validation failed for MessageId with ID = %s", ref);
	return 1;
      }

  } else {
    AXIS2_LOG_WARNING(env->log, AXIS2_LOG_SI, "[euca-rampart] node %s is UNKNOWN", ref); 
  }

    return 0;
}
/*Public functions*/
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_shb_ensure_sec_header_order(const axutil_env_t *env,
                                    axis2_msg_ctx_t *msg_ctx,
                                    rampart_context_t *rampart_context,
                                    axiom_node_t* sec_node)
{
    axis2_bool_t signature_protection = AXIS2_FALSE;
    axis2_bool_t is_encrypt_before_sign = AXIS2_FALSE;
    axiom_node_t *sig_node = NULL;
    axiom_node_t *enc_key_node = NULL;
    axiom_node_t *ref_list_node = NULL;
    axiom_node_t *h_node = NULL;
    axutil_array_list_t *dk_list = NULL;
    axutil_array_list_t *enc_key_list = NULL;
    axiom_node_t* first_protection_item = NULL;
    int i = 0;

    signature_protection = rampart_context_is_encrypt_signature(rampart_context, env);
    is_encrypt_before_sign = rampart_context_is_encrypt_before_sign(rampart_context, env);

    dk_list = axutil_array_list_create(env, 5);
    enc_key_list = axutil_array_list_create(env, 2);

    h_node = axiom_node_get_first_child(sec_node, env);
    while(h_node)
    {
        if(0 == axutil_strcmp(OXS_NODE_DERIVED_KEY_TOKEN, axiom_util_get_localname(h_node, env)) ||
                (0 == axutil_strcmp(OXS_NODE_BINARY_SECURITY_TOKEN, axiom_util_get_localname(h_node, env))))
        {
            axutil_array_list_add(dk_list, env, h_node);
        }
        else if((0 == axutil_strcmp(OXS_NODE_ENCRYPTED_KEY, axiom_util_get_localname(h_node, env))) ||
                (0 == axutil_strcmp(OXS_NODE_SECURITY_CONTEXT_TOKEN, axiom_util_get_localname(h_node, env))))
        {
            axutil_array_list_add(enc_key_list, env, h_node);
        }
        h_node = axiom_node_get_next_sibling(h_node, env);
    }

    ref_list_node = oxs_axiom_get_first_child_node_by_name(env, sec_node, OXS_NODE_REFERENCE_LIST, OXS_ENC_NS, NULL);
    sig_node = oxs_axiom_get_first_child_node_by_name(env, sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, NULL);

    /*Ensure the protection order in the header*/
    if(sig_node && ref_list_node)
    {
        if(is_encrypt_before_sign)
        {
            int no_of_sig_node = 0;
            /*Encrypt->Sig         <Sig><RefList>*/
            oxs_axiom_interchange_nodes(env,  sig_node, ref_list_node );
            first_protection_item = sig_node;
            no_of_sig_node = oxs_axiom_get_number_of_children_with_qname(env, sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, NULL);
            if(no_of_sig_node > 1)
            {
                axiom_node_t* cur_node = NULL;
                cur_node = axiom_node_get_first_child(sec_node, env);
                while(cur_node)
                {
                    axis2_char_t *cur_local_name = NULL;
                    cur_local_name = axiom_util_get_localname(cur_node, env);

                    if(0 == axutil_strcmp(cur_local_name, OXS_NODE_SIGNATURE))
                    {
                        oxs_axiom_interchange_nodes(env,  cur_node, ref_list_node);
                    }
                    cur_node = axiom_node_get_next_sibling(cur_node, env);
                }
            }
        }
        else
        {
            /*Sig->Encrypt         <RefList> <Sig>*/
            oxs_axiom_interchange_nodes(env, ref_list_node, sig_node );
            first_protection_item = ref_list_node;
        }
    }
    else if(sig_node)
    {
        first_protection_item = sig_node;
    }
    else
    {
        first_protection_item = ref_list_node;
    }

    /*makesure enc_key_node is appearing before first protection item*/
    if(first_protection_item)
    {
        for(i = 0; i < axutil_array_list_size(enc_key_list, env); i++)
        {
            axiom_node_t *tmp_node = NULL;
            tmp_node = (axiom_node_t*)axutil_array_list_get(enc_key_list, env, i);
            enc_key_node = axiom_node_detach_without_namespaces(tmp_node, env);
            axiom_node_insert_sibling_before(first_protection_item, env, enc_key_node);
        }
    }

    /*
     * If there are derived keys, make sure they come after the EncryptedKey/security context token
        1. First we get all the derived keys
        2. Then we attach after the EncryptedKey(hidden sessionkey)/security context token 
        3. If key is not available, then attach derived keys before sig_node and ref_list_node (whichever is first)
     */

    if(enc_key_node)
    {
        for(i = 0; i < axutil_array_list_size(dk_list, env); i++)
        {
            axiom_node_t *dk_node = NULL;
            axiom_node_t *tmp_node = NULL;

            dk_node = (axiom_node_t*)axutil_array_list_get(dk_list, env, i);
            tmp_node = axiom_node_detach(dk_node, env);
            axiom_node_insert_sibling_after(enc_key_node, env, tmp_node);
        }
    }
    else
    {
        if(first_protection_item)
        {
            for(i = 0; i < axutil_array_list_size(dk_list, env); i++)
            {
                axiom_node_t *dk_node = NULL;
                axiom_node_t *tmp_node = NULL;
                dk_node = (axiom_node_t*)axutil_array_list_get(dk_list, env, i);
                tmp_node = axiom_node_detach(dk_node, env);
                axiom_node_insert_sibling_before(first_protection_item, env, tmp_node);
            }
        }
    }
    
    axutil_array_list_free(dk_list, env);
    axutil_array_list_free(enc_key_list, env);
    return AXIS2_SUCCESS;
}
/**
 * Extract certificate/session_key related information using given key_info node and scope node
 * This will extract either certificate(asymmetric signing) or session_key (symmetric signing)
 * @param env Environment structure
 * @param key_info_node key info node.
 * @param rampart_context rampart context where key details could be found.
 * @param msg_ctx message context
 * @param is_signature boolean denoting whether the key_info is for signature
 * @param cert where the certificate extracted (if any) should be populated
 * @param key where the session key extracted (if any) should be populated
 * @return status of the operation
 */
AXIS2_EXTERN axis2_status_t AXIS2_CALL
rampart_token_process_key_info(
    const axutil_env_t *env,
    axiom_node_t *key_info_node,
    axiom_node_t *sec_node,
    rampart_context_t* rampart_context,
    axis2_msg_ctx_t *msg_ctx,
    axis2_bool_t is_signature,
    oxs_x509_cert_t **cert,
    oxs_key_t **key,
    axis2_char_t **token_type,
    axis2_char_t **reference_method)
{
    axiom_node_t *str_node = NULL;
    axis2_status_t status = AXIS2_FAILURE;

    /* Get the SecurityTokenReference, which is the common case, but not the only case */
    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;

        /* A <wsse:SecurityTokenReference> element MAY reference an X.509 token type
         * by one of the following means:
         *  - Reference to a Subject Key Identifier (<wsse:KeyIdentifier>)
         *  - Reference to a Binary Security Token (<wsse:Reference> element that
         *    references a local <wsse:BinarySecurityToken> element or a remote data
         *    source that contains the token data itself)
         *  - Reference to an Issuer and Serial Number (<ds:X509Data> element that
         *    contains a <ds:X509IssuerSerial> element that uniquely identifies an
         *    end entity certificate)
         */
        str_child_node = axiom_node_get_first_element(str_node, env);
        if(!str_child_node)
        {
             AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "No Child node in the Security Token Reference Element.");
            return AXIS2_FAILURE;
        }

        *reference_method = axiom_util_get_localname(str_child_node, env);
        if(!*reference_method)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Cannot get the key Reference Type from the message.");
            return AXIS2_FAILURE;
        }

        if(0 == axutil_strcmp(*reference_method, OXS_NODE_REFERENCE))
        {
            status = rampart_token_process_direct_ref(env, str_child_node, sec_node, msg_ctx,
                rampart_context, cert, key, token_type);
        }
        else if(0 == axutil_strcmp(*reference_method, OXS_NODE_EMBEDDED))
        {
            /* embedded tokens are only possible with x509 token */
            status = rampart_token_process_embedded(env, str_child_node, cert);
        }
        else if(0 == axutil_strcmp(*reference_method, OXS_NODE_KEY_IDENTIFIER))
        {
            status = rampart_token_process_key_identifier(env, str_child_node, sec_node, str_node,
                rampart_context, is_signature, cert, key, token_type);
        }
        else if(0 == axutil_strcmp(*reference_method, OXS_NODE_X509_DATA))
        {
            /* <ds:X509Data> contains a <ds:X509IssuerSerial> element which is used to specify a
             * reference to an X.509 security token by means of the certificate issuer name and
             * serial number. */
            *cert = rampart_token_process_issuer_serial(env, rampart_context, str_child_node);
            status = AXIS2_SUCCESS;
        }
        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Key Reference %s not supported ",
                *reference_method);
            return AXIS2_FAILURE;
        }
    }
    else
    {
        /* There may be scenarios where there is no Security Token Reference Element. */

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

        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to key from key_info node");
        return AXIS2_FAILURE;
    }

    if((status != AXIS2_SUCCESS) || ((!*cert) && (!*key)))
    {
        /* either status is AXIS2_FAILURE or both cert and key are NULL. This means error */
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get key/certificate from key info node");
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}
/**
 * extract certificate/key using reference id given in reference node
 */
static axis2_status_t
rampart_token_process_direct_ref(
    const axutil_env_t *env,
    axiom_node_t *ref_node,
    axiom_node_t *scope_node,
    axis2_msg_ctx_t *msg_ctx,
    rampart_context_t *rampart_context,
    oxs_x509_cert_t **cert,
    oxs_key_t **key,
    axis2_char_t **token_type)
{
    axis2_char_t *ref_id = NULL;
    axis2_bool_t external_reference = AXIS2_TRUE;

    /* Get the reference value in the @URI */
    ref_id = oxs_token_get_reference(env, ref_node);
    *token_type = oxs_token_get_reference_value_type(env, ref_node);

    if(!ref_id)
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to get key name from reference node");
        return AXIS2_FAILURE;
    }

    if(ref_id[0] == '#')
    {
        /* Need to remove # sign from the ID */
        axis2_char_t *id = NULL;
        id = axutil_string_substring_starting_at(axutil_strdup(env, ref_id), 1);
        external_reference = AXIS2_FALSE;
        ref_id = id;
        if(!ref_id)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to get key name from reference node");
            return AXIS2_FAILURE;
        }
    }

    if(!external_reference)
    {
        /* this could point to binary security token, which means it is x509 token */
        axiom_node_t *bst_node = NULL;
        axis2_char_t *data = NULL;

        bst_node = oxs_axiom_get_node_by_id(env, scope_node, OXS_ATTR_ID, ref_id, OXS_WSU_XMLNS);
        if(bst_node)
        {
            axis2_char_t *local_name = NULL;
            local_name = axiom_util_get_localname(bst_node, env);
            if(!axutil_strcmp(local_name, OXS_NODE_BINARY_SECURITY_TOKEN))
            {
                /* This is an X509 token */
                *token_type = oxs_token_get_reference_value_type(env, bst_node);

                /* Process data. */
                data = oxs_axiom_get_node_content(env, bst_node);
                *cert = oxs_key_mgr_load_x509_cert_from_string(env, data);
                if(*cert)
                {
                    return AXIS2_SUCCESS;
                }
                else
                {
                    AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                        "Cannot load certificate from string =%s", data);
                    return AXIS2_FAILURE;
                }
            }
        }
    }

    *key = rampart_context_get_key(rampart_context, env, ref_id);
    if(!(*key) && external_reference)
    {
        if((0 == axutil_strcmp(*token_type, OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN_05_02)) ||
            (0 == axutil_strcmp(*token_type, OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN_05_12)))
        {
            rampart_shp_add_security_context_token(env, ref_id, ref_id, rampart_context, msg_ctx);
        }
        *key = rampart_context_get_key(rampart_context, env, ref_id);
    }

    if(!(*key))
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot find key referenced by URI %s", ref_id);
        return AXIS2_FAILURE;
    }
    return AXIS2_SUCCESS;
}