blob: 9b225666fcac307513ecd27b96eb9069ebbe6f9a [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 <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;
}