src/omxmlsec/derivation.c (193 lines of code) (raw):

/* * 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 <axis2_util.h> #include <oxs_derivation.h> #include <oxs_key.h> #include <oxs_error.h> #include <oxs_utility.h> #include <oxs_asym_ctx.h> #include <oxs_tokens.h> #include <openssl_hmac.h> #if 0 /*Remove this funciton if not in use*/ AXIS2_EXTERN oxs_key_t* AXIS2_CALL oxs_derivation_get_the_referenced_base_key(const axutil_env_t *env, axiom_node_t *dk_token_node, axiom_node_t *root_node) { axiom_node_t *str_node = NULL; axiom_node_t *ref_node = NULL; axiom_node_t *refed_node = NULL; axis2_char_t *ref_val = NULL; axis2_char_t *id = NULL; str_node = oxs_axiom_get_first_child_node_by_name(env, dk_token_node, OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL); ref_node = oxs_axiom_get_first_child_node_by_name(env, str_node, OXS_NODE_REFERENCE, OXS_WSSE_XMLNS, NULL); if(!ref_node) {return NULL ;} ref_val = oxs_token_get_reference(env, ref_node); if(!ref_val) {return NULL ;} /*Need to remove # sign from the ID*/ id = axutil_string_substring_starting_at(ref_val, 1); /*Search for an element with the val(@Id)=@URI*/ refed_node = oxs_axiom_get_node_by_id(env, root_node, OXS_ATTR_ID, id, NULL); if(!refed_node){ oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_INVALID_DATA, "Cannot find the referenced key for the derived key"); return NULL; } return NULL; } #endif AXIS2_EXTERN oxs_key_t* AXIS2_CALL oxs_derivation_extract_derived_key_from_token( const axutil_env_t *env, axiom_node_t *dk_token_node, axiom_node_t *root_node, oxs_key_t *session_key) { oxs_key_t *base_key = NULL; oxs_key_t *derived_key = NULL; axiom_node_t *nonce_node = NULL; axiom_node_t *length_node = NULL; axiom_node_t *offset_node = NULL; axis2_status_t status = AXIS2_FAILURE; axis2_char_t *nonce = NULL; axis2_char_t *id = NULL; axiom_element_t *dk_token_element = NULL; axis2_char_t *wsc_ns_uri = NULL; /* Default values */ int offset = 0; int length = 0; /* If the session_key is NULL then extract it form the refered EncryptedKey. Otherwise use it */ if(!session_key) { /* TODO Lots of work including decrypting the EncryptedKey */ } else { base_key = session_key; } dk_token_element =(axiom_element_t *) axiom_node_get_data_element(dk_token_node, env); if (dk_token_element) { axutil_qname_t *node_qname = NULL; node_qname = axiom_element_get_qname(dk_token_element, env, dk_token_node); if(!node_qname) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart] Cannot get qname from dervied key token."); return NULL; } wsc_ns_uri = axutil_qname_get_uri(node_qname, env); } if(!wsc_ns_uri) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart] Cannot get namespace from dervied key token."); return NULL; } /* Get offset value */ offset_node = oxs_axiom_get_first_child_node_by_name( env, dk_token_node, OXS_NODE_OFFSET, wsc_ns_uri, NULL); if(offset_node) { offset = oxs_token_get_offset_value(env, offset_node); } /* Get length value */ length_node = oxs_axiom_get_first_child_node_by_name( env, dk_token_node, OXS_NODE_LENGTH, wsc_ns_uri, NULL); if(length_node) { length = oxs_token_get_length_value(env, length_node); } /* Get nonce value */ nonce_node = oxs_axiom_get_first_child_node_by_name( env, dk_token_node, OXS_NODE_NONCE, wsc_ns_uri, NULL); if(nonce_node) { nonce = oxs_token_get_nonce_value(env, nonce_node); } /* Create a new(empty) key as the derived key */ derived_key = oxs_key_create(env); oxs_key_set_offset(derived_key, env, offset); oxs_key_set_nonce(derived_key, env, nonce); oxs_key_set_length(derived_key, env, length); /* Now derive the key using the base_key and other parematers */ status = oxs_derivation_derive_key(env, base_key, derived_key, AXIS2_FALSE); if(status != AXIS2_SUCCESS) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot derive the key from given element."); oxs_key_free(derived_key, env); derived_key = NULL; } /* We need to set the name of the derived key */ id = oxs_axiom_get_attribute_value_of_node_by_name( env, dk_token_node, OXS_ATTR_ID, OXS_WSU_XMLNS); oxs_key_set_name(derived_key, env, id); AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[rampart] DK=%s derived from Sk=%s ", id , oxs_key_get_name(base_key, env) ); return derived_key; } AXIS2_EXTERN axiom_node_t * AXIS2_CALL oxs_derivation_build_derived_key_token( const axutil_env_t *env, oxs_key_t *derived_key, axiom_node_t *parent, axis2_char_t *stref_uri, axis2_char_t *stref_val_type, axis2_char_t *wsc_ns_uri) { axiom_node_t *str_token = NULL; axiom_node_t *ref_token = NULL; axis2_char_t *uri = NULL; uri = axutil_stracat(env, OXS_LOCAL_REFERENCE_PREFIX, stref_uri); str_token = oxs_token_build_security_token_reference_element(env, NULL); ref_token = oxs_token_build_reference_element(env, str_token, uri, stref_val_type); AXIS2_FREE(env->allocator, uri); return oxs_derivation_build_derived_key_token_with_stre( env, derived_key, parent, str_token, wsc_ns_uri); } AXIS2_EXTERN axiom_node_t * AXIS2_CALL oxs_derivation_build_derived_key_token_with_stre(const axutil_env_t *env, oxs_key_t *derived_key, axiom_node_t *parent, axiom_node_t *stre, axis2_char_t *wsc_ns_uri) { axiom_node_t *dk_token = NULL; axiom_node_t *nonce_token = NULL; axiom_node_t *offset_token = NULL; axiom_node_t *length_token = NULL; /*axiom_node_t *label_token = NULL;*/ axis2_char_t *dk_id = NULL; axis2_char_t *dk_name = NULL; axis2_char_t *nonce = NULL; axis2_char_t *label = NULL; int offset = -1; int length = 0; dk_name = oxs_key_get_name(derived_key, env); dk_id = axutil_string_substring_starting_at(dk_name, 1); dk_token = oxs_token_build_derived_key_token_element(env, parent, dk_id, NULL, wsc_ns_uri); axiom_node_add_child(dk_token, env, stre); /* Create offset */ offset = oxs_key_get_offset(derived_key, env); if(offset > -1) { offset_token = oxs_token_build_offset_element(env, dk_token, offset, wsc_ns_uri); } /* Create length */ length = oxs_key_get_length(derived_key, env); if(length > 0) { length_token = oxs_token_build_length_element(env, dk_token, length, wsc_ns_uri); } /* Create nonce */ nonce = oxs_key_get_nonce(derived_key, env); if(nonce) { nonce_token = oxs_token_build_nonce_element(env, dk_token, nonce, wsc_ns_uri); } /* Create label. Hmm we dont need to send the label. Use the default. */ label = oxs_key_get_label(derived_key, env); /*if(label) { label_token = oxs_token_build_label_element(env, dk_token, label, wsc_ns_uri); }*/ return dk_token; } AXIS2_EXTERN axis2_status_t AXIS2_CALL oxs_derivation_derive_key( const axutil_env_t *env, oxs_key_t *secret, oxs_key_t *derived_key, axis2_bool_t build) { axis2_status_t status = AXIS2_FAILURE; /* TODO check for derivation algorithm */ if (build) { status = openssl_p_sha1(env, secret, NULL, NULL, derived_key); } else { status = openssl_p_sha1(env, secret, oxs_key_get_label(derived_key, env), oxs_key_get_nonce(derived_key, env), derived_key); } return status; }