You are viewing a plain text version of this content. The canonical link for it is here.
Posted to rampart-dev@ws.apache.org by sh...@apache.org on 2008/06/25 12:53:48 UTC
svn commit: r671507 [2/2] - in /webservices/rampart/trunk/c: build/win32/
ides/Rampart/Rampart/ include/ samples/client/sec_echo/
samples/sct_provider/ samples/secpolicy/ samples/secpolicy/scenario25/
samples/secpolicy/scenario26/ samples/server/sec_ec...
Added: webservices/rampart/trunk/c/src/rahas/rahas_request_processor.c
URL: http://svn.apache.org/viewvc/webservices/rampart/trunk/c/src/rahas/rahas_request_processor.c?rev=671507&view=auto
==============================================================================
--- webservices/rampart/trunk/c/src/rahas/rahas_request_processor.c (added)
+++ webservices/rampart/trunk/c/src/rahas/rahas_request_processor.c Wed Jun 25 03:53:47 2008
@@ -0,0 +1,499 @@
+/*
+ * 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 <secconv_security_context_token.h>
+#include <axutil_utils_defines.h>
+#include <axutil_env.h>
+#include <trust_rst.h>
+#include <trust_rstr.h>
+#include <oxs_buffer.h>
+#include <rampart_constants.h>
+#include <rampart_context.h>
+#include <openssl_hmac.h>
+#include <oxs_utility.h>
+#include <openssl_util.h>
+
+static security_context_token_t *
+rahas_create_security_context_token(
+ const axutil_env_t *env,
+ axis2_bool_t server_entropy_needed,
+ trust_entropy_t *requester_entropy,
+ int key_size,
+ oxs_buffer_t **server_secret);
+
+static axis2_status_t
+rahas_store_security_context_token(
+ const axutil_env_t *env,
+ security_context_token_t *sct,
+ axis2_msg_ctx_t *msg_ctx);
+
+AXIS2_EXTERN axis2_status_t AXIS2_CALL
+rahas_process_issue_request(
+ const axutil_env_t *env,
+ trust_rst_t *rst,
+ trust_rstr_t *rstr,
+ axis2_msg_ctx_t *msg_ctx,
+ int trust_version)
+{
+ trust_entropy_t* requester_entropy = NULL;
+ oxs_buffer_t *server_secret = NULL;
+ security_context_token_t *sct = NULL;
+ axis2_bool_t client_entropy_needed = AXIS2_FALSE;
+ axis2_bool_t server_entropy_needed = AXIS2_FALSE;
+ int key_size = TRUST_DEFAULT_KEY_SIZE;
+
+ /* validate whether given parameters are ok to proceed */
+ if(rahas_validate_issue_request_parameters(env, rst, rstr, msg_ctx, trust_version,
+ client_entropy_needed, &requester_entropy) != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot issue SecurityContextToken because parameter validation failed.");
+ return AXIS2_FAILURE;
+ }
+
+ /* check whether client entropy and server entropy are needed */
+ if (rahas_find_sts_policy(env, msg_ctx, &client_entropy_needed, &server_entropy_needed)
+ != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot issue SecurityContextToken because security token service policy "
+ "could not be found.");
+ return AXIS2_FAILURE;
+ }
+
+
+ /* Get the size of the key*/
+ key_size = trust_rst_get_key_size(rst, env);
+
+ /* size is not a compulsary field. If missing, we can use default size */
+ if(key_size <= 0)
+ {
+ key_size = TRUST_DEFAULT_KEY_SIZE;
+ }
+
+ /* Create sct and populate it */
+ sct = rahas_create_security_context_token(
+ env, server_entropy_needed, requester_entropy, key_size, &server_secret);
+ if(!sct)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot issue SecurityContextToken because SCT creation failed.");
+ return AXIS2_FAILURE;
+ }
+
+ /* store SCT so that when server needs it, can be extracted. It is the responsibility of the
+ * storing implementer to switch to global pool if needed */
+ if(rahas_store_security_context_token(env, sct, msg_ctx) != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rahas]Cannot store SecurityContextToken.");
+ security_context_token_free(sct, env);
+ return AXIS2_FAILURE;
+ }
+
+ /* Populate rstr structure */
+ if (rahas_populate_rstr_for_issue_request(env, rstr, trust_version,
+ client_entropy_needed, server_secret, sct, key_size) != AXIS2_SUCCESS)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot issue SecurityContextToken because response createion failed.");
+ security_context_token_free(sct, env);
+ return AXIS2_FAILURE;
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+static axis2_status_t
+rahas_validate_issue_request_parameters(
+ const axutil_env_t *env,
+ trust_rst_t *rst,
+ trust_rstr_t *rstr,
+ axis2_msg_ctx_t *msg_ctx,
+ int trust_version,
+ axis2_bool_t client_entropy_needed,
+ trust_entropy_t** requester_entropy)
+{
+ axis2_char_t *token_type = NULL;
+ axis2_char_t *expected_token_type = NULL;
+
+ if(!rst)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Given RequestSecurityToken structure is not valid.");
+ return AXIS2_FAILURE;
+ }
+
+ if(!rstr)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Given RequestSecurityTokenResponse structure is not valid.");
+ return AXIS2_FAILURE;
+ }
+
+ if(!msg_ctx)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Given Message context structure is not valid.");
+ return AXIS2_FAILURE;
+ }
+
+ /* check whether trust version is valid, and if so, get trust version specific constants */
+ if(trust_version == TRUST_VERSION_05_02)
+ {
+ expected_token_type = OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN;
+ }
+ else if(trust_version == TRUST_VERSION_05_12)
+ {
+ expected_token_type = OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN_05_12;
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Given trust specification version is not valid or not supported.");
+ return AXIS2_FAILURE;
+ }
+
+ /* check whether token type is valid and can be processed */
+ token_type = trust_rst_get_token_type(rst, env);
+ if(!token_type)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rahas]Token type is not given.");
+ return AXIS2_FAILURE;
+ }
+
+ if(axutil_strcmp(token_type, expected_token_type))
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Given token type [%s] is not valid. Expected token type is [%s]",
+ token_type, expected_token_type);
+ return AXIS2_FAILURE;
+ }
+
+ /* check whether client entropy is needed according to policy and whether it is provided */
+ *requester_entropy = trust_rst_get_entropy(rst, env);
+ if(client_entropy_needed)
+ {
+ if(!*requester_entropy)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Client entropy is expected, but not given by client.");
+ return AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ if(*requester_entropy)
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Client entropy is not expected, but it is given by client.");
+ return AXIS2_FAILURE;
+ }
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+static security_context_token_t *
+rahas_create_security_context_token(
+ const axutil_env_t *env,
+ axis2_bool_t server_entropy_needed,
+ trust_entropy_t *requester_entropy,
+ int key_size,
+ oxs_buffer_t **server_secret)
+{
+ axis2_char_t *global_id = NULL;
+ axis2_char_t *local_id = NULL;
+ security_context_token_t *sct = NULL;
+
+ /* given key size will be in bits. Convert into bytes */
+ int key_size_in_byte = key_size / 8;
+
+ /* we are going to create objects which will be shared among multiple requests. So we have to
+ * create in global pool */
+ axutil_allocator_switch_to_global_pool(env->allocator);
+
+ /* create security context token */
+ sct = security_context_token_create(env);
+ if(!sct)
+ {
+ axutil_allocator_switch_to_local_pool(env->allocator);
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot create security context token. Insufficient memory.");
+ return NULL;
+ }
+
+ /* create global id, local id */
+ global_id = oxs_util_generate_id(env, SECCONV_GLOBAL_ID_PREFIX);
+ local_id = axutil_stracat(env, "#", oxs_util_generate_id(env, SECCONV_LOCAL_ID_PREFIX));
+
+ /* check whether server secret is needed. If specifically said "server entropy needed" then
+ * no problem. If not said specifically, and if client entropy is not there, then again we have
+ * to provide a shared secret */
+ if((server_entropy_needed) || (!requester_entropy))
+ {
+ int server_secret_size = key_size_in_byte;
+ /* if client entropy is given, our entropy should be half of the size given */
+ if(requester_entropy)
+ {
+ server_secret_size = server_secret_size / 2;
+ }
+ *server_secret = oxs_buffer_create(env);
+ openssl_generate_random_data(env, *server_secret, server_secret_size);
+ }
+
+ /* populate security context token */
+ security_context_token_set_global_identifier(sct, env, global_id);
+ security_context_token_set_local_identifier(sct, env, local_id);
+
+ if(requester_entropy)
+ {
+ axis2_char_t *requester_nonce = NULL;
+ int requester_entropy_len = 0;
+ axis2_char_t *decoded_requester_entropy = NULL;
+ oxs_buffer_t *buffer = NULL;
+
+ /* client entropy will be in base64 format. should decode it */
+ requester_nonce = trust_entropy_get_binary_secret(requester_entropy, env);
+ requester_entropy_len = axutil_base64_decode_len(requester_nonce);
+ decoded_requester_entropy = AXIS2_MALLOC(env->allocator, requester_entropy_len);
+ axutil_base64_decode_binary((unsigned char*)decoded_requester_entropy, requester_nonce);
+ buffer = oxs_buffer_create(env);
+
+ if(server_entropy_needed)
+ {
+ /* we have client entropy and server entropy. so shared secret will be combined key */
+ axis2_char_t *output = NULL;
+
+ output = AXIS2_MALLOC(env->allocator, key_size);
+ openssl_p_hash(env,
+ (unsigned char*)decoded_requester_entropy, requester_entropy_len,
+ oxs_buffer_get_data(*server_secret, env), oxs_buffer_get_size(*server_secret, env),
+ (unsigned char*)output, key_size_in_byte);
+ oxs_buffer_populate(buffer, env, (unsigned char*)output, key_size_in_byte);
+ }
+ else
+ {
+ /* we have to use client entropy as the sct shared secret */
+ oxs_buffer_populate(
+ buffer, env, (unsigned char*)decoded_requester_entropy, requester_entropy_len);
+ }
+
+ security_context_token_set_secret(sct, env, buffer);
+ }
+ else
+ {
+ /* we have to use server entropy as the sct shared secret */
+ security_context_token_set_secret(sct, env, *server_secret);
+ }
+
+ /* we are done with creating the SCT. Now we can switch back to local pool */
+ axutil_allocator_switch_to_local_pool(env->allocator);
+
+ return sct;
+}
+
+static axis2_status_t
+rahas_populate_rstr_for_issue_request(
+ const axutil_env_t *env,
+ trust_rstr_t *rstr,
+ int trust_version,
+ axis2_bool_t client_entropy_needed,
+ oxs_buffer_t *server_secret,
+ security_context_token_t *sct,
+ int key_size)
+{
+ axis2_char_t *token_type = NULL;
+ axis2_char_t *trust_ns_uri = NULL;
+ axis2_char_t *computed_key_algo = NULL;
+
+ /* Get trust version specific constants */
+ if(trust_version == TRUST_VERSION_05_02)
+ {
+ trust_ns_uri = TRUST_WST_XMLNS_05_02;
+ token_type = OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN;
+ computed_key_algo = TRUST_COMPUTED_KEY_PSHA1;
+ }
+ else if(trust_version == TRUST_VERSION_05_12)
+ {
+ trust_ns_uri = TRUST_WST_XMLNS_05_12;
+ token_type = OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN_05_12;
+ computed_key_algo = TRUST_COMPUTED_KEY_PSHA1_05_12;
+ }
+
+ /* We have to populate issue request specific items.
+ * (1) Token Type
+ * (2) Attached reference
+ * (3) Unattached reference
+ * (4) SCT representation
+ * (5) Shared secret.
+ * We are assuming request_type, namespace, etc. are already populated. */
+ trust_rstr_set_token_type(rstr, env, token_type);
+ trust_rstr_set_requested_unattached_reference(rstr, env,
+ security_context_token_get_unattached_reference(sct, env));
+ trust_rstr_set_requested_attached_reference(rstr, env,
+ security_context_token_get_attached_reference(sct, env));
+ trust_rstr_set_requested_security_token(rstr, env,
+ security_context_token_get_token(sct, env));
+
+ /* we have to send the key detail to client.
+ * (1) If client entropy and server entropy is used, we have to send server entropy and computed
+ key
+ * (2) If only server entropy is used, then we have to send entropy as proof token
+ * (3) If only client entropy is used, then we don't have to send anything.
+ */
+ if((client_entropy_needed) && (server_secret))
+ {
+ /* we have to send computed key and entropy */
+ axis2_char_t *nonce = NULL;
+ trust_entropy_t* entropy = NULL;
+ axiom_node_t *computed_key = NULL;
+ axiom_element_t *computed_key_element = NULL;
+ axiom_node_t *requested_proof = NULL;
+
+ /* if client and server entropy are there, then server entropy will be half the key_size.
+ * Also, key size is in bits. So, actual server_entropy size is key_size / 16 */
+ int size = key_size / 16;
+
+ trust_rstr_set_key_size(rstr, env, key_size);
+ nonce = AXIS2_MALLOC(env->allocator, sizeof(char) * (axutil_base64_encode_len(size)+1));
+ axutil_base64_encode(nonce, (char*)oxs_buffer_get_data(server_secret, env), size);
+
+ entropy = trust_entropy_create(env);
+ trust_entropy_set_binary_secret(entropy, env, nonce);
+ trust_entropy_set_ns_uri(entropy, env, trust_ns_uri);
+ trust_entropy_set_binary_secret_type(entropy, env, NONCE);
+ trust_rstr_set_entropy(rstr, env, entropy);
+
+ computed_key = trust_util_computed_key_element(env, trust_ns_uri, NULL);
+ computed_key_element = axiom_node_get_data_element(computed_key, env);
+ axiom_element_set_text(computed_key_element, env, computed_key_algo, computed_key);
+ requested_proof = trust_util_create_requsted_proof_token_element(
+ env, trust_ns_uri, NULL, computed_key);
+ trust_rstr_set_requested_proof_token(rstr, env, requested_proof);
+ }
+ else if(!client_entropy_needed)
+ {
+ /* server key only. so have to send proof token */
+ trust_rstr_set_requested_proof_token(
+ rstr, env, security_context_token_get_requested_proof_token(sct, env));
+ }
+
+ return AXIS2_SUCCESS;
+}
+
+static axis2_status_t
+rahas_store_security_context_token(
+ const axutil_env_t *env,
+ security_context_token_t *sct,
+ axis2_msg_ctx_t *msg_ctx)
+{
+ axutil_property_t *property = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, RAMPART_CONTEXT);
+ if(property)
+ {
+ rampart_context_t *rampart_context = NULL;
+ rampart_context = (rampart_context_t *)axutil_property_get_value(property, env);
+ if(rampart_context)
+ {
+ store_security_context_token_fn store_fn = NULL;
+ void *user_param = NULL;
+
+ store_fn = rampart_context_get_store_security_context_token_fn(rampart_context, env);
+ user_param = rampart_context_get_security_context_token_user_params(
+ rampart_context, env);
+ status = store_fn(env, msg_ctx, security_context_token_get_global_identifier(sct, env),
+ security_context_token_get_local_identifier(sct, env), sct, user_param);
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot find rampart context. Cannot store security context token.");
+ status = AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot find rampart context property. Cannot store security context token.");
+ status = AXIS2_FAILURE;
+ }
+
+ return status;
+}
+
+static axis2_status_t
+rahas_find_sts_policy(
+ const axutil_env_t *env,
+ axis2_msg_ctx_t *msg_ctx,
+ axis2_bool_t *client_entropy_needed,
+ axis2_bool_t *server_entropy_needed)
+{
+ axutil_property_t *property = NULL;
+ axis2_status_t status = AXIS2_SUCCESS;
+
+ property = axis2_msg_ctx_get_property(msg_ctx, env, RAMPART_CONTEXT);
+ if(property)
+ {
+ rampart_context_t *rampart_context = NULL;
+ rampart_context = (rampart_context_t *)axutil_property_get_value(property, env);
+ if(rampart_context)
+ {
+ rp_secpolicy_t *sec_policy = NULL;
+ sec_policy = rampart_context_get_secpolicy(rampart_context, env);
+ if(sec_policy)
+ {
+ rp_trust10_t *trust_policy = NULL;
+ trust_policy = rp_secpolicy_get_trust10(sec_policy, env);
+ if(trust_policy)
+ {
+ *client_entropy_needed = rp_trust10_get_require_client_entropy(trust_policy, env);
+ *server_entropy_needed = rp_trust10_get_require_server_entropy(trust_policy, env);
+ }
+ else
+ {
+ *client_entropy_needed = AXIS2_FALSE;
+ *server_entropy_needed = AXIS2_FALSE;
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot find security policy related to security context token service "
+ "from rampart context.");
+ status = AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot find rampart context. "
+ "Cannot find policy related to security context token service.");
+ status = AXIS2_FAILURE;
+ }
+ }
+ else
+ {
+ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
+ "[rahas]Cannot find rampart context property. "
+ "Cannot find policy related to security context token service.");
+ status = AXIS2_FAILURE;
+ }
+
+ return status;
+}
\ No newline at end of file
Modified: webservices/rampart/trunk/c/src/secconv/sct_provider.c
URL: http://svn.apache.org/viewvc/webservices/rampart/trunk/c/src/secconv/sct_provider.c?rev=671507&r1=671506&r2=671507&view=diff
==============================================================================
--- webservices/rampart/trunk/c/src/secconv/sct_provider.c (original)
+++ webservices/rampart/trunk/c/src/secconv/sct_provider.c Wed Jun 25 03:53:47 2008
@@ -68,8 +68,8 @@
if(!token)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "[rampart]rampart policy property 'token' is not valid. Could not find whether \
- token is SecureConversationToken or SecurityContextToken.");
+ "[rampart]rampart policy property 'token' is not valid. Could not find whether "
+ "token is SecureConversationToken or SecurityContextToken.");
return NULL;
}
@@ -77,8 +77,8 @@
if(!rp_sct)
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "[rampart]value of rampart policy property 'token' is not valid. Could not find \
- whether token is SecureConversationToken or SecurityContextToken.");
+ "[rampart]value of rampart policy property 'token' is not valid. Could not find "
+ "whether token is SecureConversationToken or SecurityContextToken.");
return NULL;
}
@@ -99,8 +99,8 @@
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "[rampart] Secure conversation token is requested without giving ID of SCT. \
- This cannot be done in server side.");
+ "[rampart] Secure conversation token is requested without giving ID of SCT. "
+ "This cannot be done in server side.");
}
}
else
@@ -379,7 +379,7 @@
trust_rst_set_request_type(rst, env, TRUST_REQ_TYPE_ISSUE);
trust_rst_set_token_type(rst, env, OXS_VALUE_TYPE_SECURITY_CONTEXT_TOKEN);
trust_rst_set_wst_ns_uri(rst, env, TRUST_WST_XMLNS_05_02);
- trust_rst_set_wsa_action(rst, env, SECCONV_200502_REQUEST_ACTION);
+ trust_rst_set_wsa_action(rst, env, SECCONV_200502_REQUEST_ISSUE_ACTION);
trust_context_set_rst(trust_context, env, rst);
/* call sts_client to get the token from sts. We should create a clone of that policy */
@@ -537,7 +537,7 @@
oxs_buffer_populate(
key_buffer, env, (unsigned char*)"01234567012345670123456701234567", 32);
security_context_token_set_secret(sct, env, key_buffer);
- sct_id = oxs_util_generate_id(env,"urn:uuid:");
+ sct_id = oxs_util_generate_id(env, SECCONV_GLOBAL_ID_PREFIX);
security_context_token_set_global_identifier(sct, env, sct_id);
security_context_token_set_local_identifier(
sct, env, axutil_strdup(env, "#sctId-29530019"));
@@ -602,8 +602,8 @@
{
/* if both local_id and global_id are NULL, then we can't store it */
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "[rampart]Security context token identifiers are not valid. \
- Cannot store security context token. ");
+ "[rampart]Security context token identifiers are not valid. "
+ "Cannot store security context token. ");
status = AXIS2_FAILURE;
}
}
Modified: webservices/rampart/trunk/c/src/util/rampart_engine.c
URL: http://svn.apache.org/viewvc/webservices/rampart/trunk/c/src/util/rampart_engine.c?rev=671507&r1=671506&r2=671507&view=diff
==============================================================================
--- webservices/rampart/trunk/c/src/util/rampart_engine.c (original)
+++ webservices/rampart/trunk/c/src/util/rampart_engine.c Wed Jun 25 03:53:47 2008
@@ -525,8 +525,8 @@
else
{
AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
- "[rampart]Cannot find 'get user param' operation of secrutiy context token \
- provider.");
+ "[rampart]Cannot find 'get user param' operation of secrutiy context token "
+ "provider.");
return AXIS2_FAILURE;
}