os/ossrv/ssl/libcrypto/src/crypto/store/str_mem.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */
     2 /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
     3  * project 2003.
     4  */
     5 /* ====================================================================
     6  * Copyright (c) 2003 The OpenSSL Project.  All rights reserved.
     7  *
     8  * Redistribution and use in source and binary forms, with or without
     9  * modification, are permitted provided that the following conditions
    10  * are met:
    11  *
    12  * 1. Redistributions of source code must retain the above copyright
    13  *    notice, this list of conditions and the following disclaimer. 
    14  *
    15  * 2. Redistributions in binary form must reproduce the above copyright
    16  *    notice, this list of conditions and the following disclaimer in
    17  *    the documentation and/or other materials provided with the
    18  *    distribution.
    19  *
    20  * 3. All advertising materials mentioning features or use of this
    21  *    software must display the following acknowledgment:
    22  *    "This product includes software developed by the OpenSSL Project
    23  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
    24  *
    25  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
    26  *    endorse or promote products derived from this software without
    27  *    prior written permission. For written permission, please contact
    28  *    openssl-core@openssl.org.
    29  *
    30  * 5. Products derived from this software may not be called "OpenSSL"
    31  *    nor may "OpenSSL" appear in their names without prior written
    32  *    permission of the OpenSSL Project.
    33  *
    34  * 6. Redistributions of any form whatsoever must retain the following
    35  *    acknowledgment:
    36  *    "This product includes software developed by the OpenSSL Project
    37  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
    38  *
    39  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
    40  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    41  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    42  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
    43  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    44  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    45  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    46  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    47  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    48  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    49  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    50  * OF THE POSSIBILITY OF SUCH DAMAGE.
    51  * ====================================================================
    52  *
    53  * This product includes cryptographic software written by Eric Young
    54  * (eay@cryptsoft.com).  This product includes software written by Tim
    55  * Hudson (tjh@cryptsoft.com).
    56  *
    57  */
    58 
    59 /*
    60  © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
    61  */
    62  
    63 #include <string.h>
    64 #include <openssl/err.h>
    65 #include "str_locl.h"
    66 #if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
    67 #include "libcrypto_wsd_macros.h"
    68 #include "libcrypto_wsd.h"
    69 #endif
    70 
    71 /* The memory store is currently highly experimental.  It's meant to become
    72    a base store used by other stores for internal caching (for full caching
    73    support, aging needs to be added).
    74 
    75    The database use is meant to support as much attribute association as
    76    possible, while providing for as small search ranges as possible.
    77    This is currently provided for by sorting the entries by numbers that
    78    are composed of bits set at the positions indicated by attribute type
    79    codes.  This provides for ranges determined by the highest attribute
    80    type code value.  A better idea might be to sort by values computed
    81    from the range of attributes associated with the object (basically,
    82    the difference between the highest and lowest attribute type code)
    83    and it's distance from a base (basically, the lowest associated
    84    attribute type code).
    85 */
    86 
    87 struct mem_object_data_st
    88 	{
    89 	STORE_OBJECT *object;
    90 	STORE_ATTR_INFO *attr_info;
    91 	int references;
    92 	};
    93 
    94 struct mem_data_st
    95 	{
    96 	STACK *data;		/* A stack of mem_object_data_st,
    97 				   sorted with STORE_ATTR_INFO_compare(). */
    98 	unsigned int compute_components : 1; /* Currently unused, but can
    99 						be used to add attributes
   100 						from parts of the data. */
   101 	};
   102 
   103 struct mem_ctx_st
   104 	{
   105 	int type;		/* The type we're searching for */
   106 	STACK *search_attributes; /* Sets of attributes to search for.
   107 				     Each element is a STORE_ATTR_INFO. */
   108 	int search_index;	/* which of the search attributes we found a match
   109 				   for, -1 when we still haven't found any */
   110 	int index;		/* -1 as long as we're searching for the first */
   111 	};
   112 
   113 static int mem_init(STORE *s);
   114 static void mem_clean(STORE *s);
   115 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
   116 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
   117 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
   118 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
   119 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
   120 	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
   121 	OPENSSL_ITEM parameters[]);
   122 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
   123 	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
   124 	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
   125 	OPENSSL_ITEM parameters[]);
   126 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
   127 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
   128 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
   129 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
   130 static STORE_OBJECT *mem_list_next(STORE *s, void *handle);
   131 static int mem_list_end(STORE *s, void *handle);
   132 static int mem_list_endp(STORE *s, void *handle);
   133 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
   134 	OPENSSL_ITEM parameters[]);
   135 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
   136 	OPENSSL_ITEM parameters[]);
   137 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void));
   138 
   139 
   140 #ifndef EMULATOR
   141 static STORE_METHOD store_memory =
   142 	{
   143 	"OpenSSL memory store interface",
   144 	mem_init,
   145 	mem_clean,
   146 	mem_generate,
   147 	mem_get,
   148 	mem_store,
   149 	mem_modify,
   150 	NULL, /* revoke */
   151 	mem_delete,
   152 	mem_list_start,
   153 	mem_list_next,
   154 	mem_list_end,
   155 	mem_list_endp,
   156 	NULL, /* update */
   157 	mem_lock,
   158 	mem_unlock,
   159 	mem_ctrl
   160 	};
   161 #else
   162 GET_STATIC_VAR_FROM_TLS(store_memory,str_mem,STORE_METHOD)
   163 #define store_memory (*GET_WSD_VAR_NAME(store_memory,str_mem, s)())
   164 const STORE_METHOD temp_s_store_memory =
   165 	{
   166 	"OpenSSL memory store interface",
   167 	mem_init,
   168 	mem_clean,
   169 	mem_generate,
   170 	mem_get,
   171 	mem_store,
   172 	mem_modify,
   173 	NULL, /* revoke */
   174 	mem_delete,
   175 	mem_list_start,
   176 	mem_list_next,
   177 	mem_list_end,
   178 	mem_list_endp,
   179 	NULL, /* update */
   180 	mem_lock,
   181 	mem_unlock,
   182 	mem_ctrl
   183 	};
   184 #endif
   185 EXPORT_C const STORE_METHOD *STORE_Memory(void)
   186 	{
   187 	return &store_memory;
   188 	}
   189 
   190 static int mem_init(STORE *s)
   191 	{
   192 	return 1;
   193 	}
   194 
   195 static void mem_clean(STORE *s)
   196 	{
   197 	return;
   198 	}
   199 
   200 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
   201 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
   202 	{
   203 	STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED);
   204 	return 0;
   205 	}
   206 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
   207 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
   208 	{
   209 	void *context = mem_list_start(s, type, attributes, parameters);
   210 	
   211 	if (context)
   212 		{
   213 		STORE_OBJECT *object = mem_list_next(s, context);
   214 
   215 		if (mem_list_end(s, context))
   216 			return object;
   217 		}
   218 	return NULL;
   219 	}
   220 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
   221 	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
   222 	OPENSSL_ITEM parameters[])
   223 	{
   224 	STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED);
   225 	return 0;
   226 	}
   227 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
   228 	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
   229 	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
   230 	OPENSSL_ITEM parameters[])
   231 	{
   232 	STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED);
   233 	return 0;
   234 	}
   235 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
   236 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
   237 	{
   238 	STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED);
   239 	return 0;
   240 	}
   241 
   242 /* The list functions may be the hardest to understand.  Basically,
   243    mem_list_start compiles a stack of attribute info elements, and
   244    puts that stack into the context to be returned.  mem_list_next
   245    will then find the first matching element in the store, and then
   246    walk all the way to the end of the store (since any combination
   247    of attribute bits above the starting point may match the searched
   248    for bit pattern...). */
   249 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
   250 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
   251 	{
   252 	struct mem_ctx_st *context =
   253 		(struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st));
   254 	void *attribute_context = NULL;
   255 	STORE_ATTR_INFO *attrs = NULL;
   256 
   257 	if (!context)
   258 		{
   259 		STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE);
   260 		return 0;
   261 		}
   262 	memset(context, 0, sizeof(struct mem_ctx_st));
   263 
   264 	attribute_context = STORE_parse_attrs_start(attributes);
   265 	if (!attribute_context)
   266 		{
   267 		STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB);
   268 		goto err;
   269 		}
   270 
   271 	while((attrs = STORE_parse_attrs_next(attribute_context)))
   272 		{
   273 		if (context->search_attributes == NULL)
   274 			{
   275 			context->search_attributes =
   276 				sk_new((int (*)(const char * const *, const char * const *))STORE_ATTR_INFO_compare);
   277 			if (!context->search_attributes)
   278 				{
   279 				STOREerr(STORE_F_MEM_LIST_START,
   280 					ERR_R_MALLOC_FAILURE);
   281 				goto err;
   282 				}
   283 			}
   284 		sk_push(context->search_attributes,(char *)attrs);
   285 		}
   286 	if (!STORE_parse_attrs_endp(attribute_context))
   287 		goto err;
   288 	STORE_parse_attrs_end(attribute_context);
   289 	context->search_index = -1;
   290 	context->index = -1;
   291 	return context;
   292  err:
   293 	if (attribute_context) STORE_parse_attrs_end(attribute_context);
   294 	mem_list_end(s, context);
   295 	return NULL;
   296 	}
   297 static STORE_OBJECT *mem_list_next(STORE *s, void *handle)
   298 	{
   299 	int i;
   300 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
   301 	struct mem_object_data_st key = { 0, 0, 1 };
   302 	struct mem_data_st *store =
   303 		(struct mem_data_st *)STORE_get_ex_data(s, 1);
   304 	int srch;
   305 	int cres = 0;
   306 
   307 	if (!context)
   308 		{
   309 		STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
   310 		return NULL;
   311 		}
   312 	if (!store)
   313 		{
   314 		STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE);
   315 		return NULL;
   316 		}
   317 
   318 	if (context->search_index == -1)
   319 		{
   320 		for (i = 0; i < sk_num(context->search_attributes); i++)
   321 			{
   322 			key.attr_info =
   323 				(STORE_ATTR_INFO *)sk_value(context->search_attributes, i);
   324 			srch = sk_find_ex(store->data, (char *)&key);
   325 
   326 			if (srch >= 0)
   327 				{
   328 				context->search_index = srch;
   329 				break;
   330 				}
   331 			}
   332 		}
   333 	if (context->search_index < 0)
   334 		return NULL;
   335 	
   336 	key.attr_info =
   337 		(STORE_ATTR_INFO *)sk_value(context->search_attributes,
   338 			context->search_index);
   339 	for(srch = context->search_index;
   340 	    srch < sk_num(store->data)
   341 		    && STORE_ATTR_INFO_in_range(key.attr_info,
   342 			    (STORE_ATTR_INFO *)sk_value(store->data, srch))
   343 		    && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
   344 				 (STORE_ATTR_INFO *)sk_value(store->data, srch)));
   345 	    srch++)
   346 		;
   347 
   348 	context->search_index = srch;
   349 	if (cres)
   350 		return ((struct mem_object_data_st *)sk_value(store->data,
   351 				srch))->object;
   352 	return NULL;
   353 	}
   354 static int mem_list_end(STORE *s, void *handle)
   355 	{
   356 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
   357 
   358 	if (!context)
   359 		{
   360 		STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER);
   361 		return 0;
   362 		}
   363 	if (context && context->search_attributes)
   364 		sk_free(context->search_attributes);
   365 	if (context) OPENSSL_free(context);
   366 	return 1;
   367 	}
   368 static int mem_list_endp(STORE *s, void *handle)
   369 	{
   370 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
   371 
   372 	if (!context
   373 		|| context->search_index == sk_num(context->search_attributes))
   374 		return 1;
   375 	return 0;
   376 	}
   377 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
   378 	OPENSSL_ITEM parameters[])
   379 	{
   380 	return 1;
   381 	}
   382 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
   383 	OPENSSL_ITEM parameters[])
   384 	{
   385 	return 1;
   386 	}
   387 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void))
   388 	{
   389 	return 1;
   390 	}