Home | History | Annotate | Download | only in store
      1 /* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */
      2 /* Written by Richard Levitte (richard (at) 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 (at) 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 (at) cryptsoft.com).  This product includes software written by Tim
     55  * Hudson (tjh (at) cryptsoft.com).
     56  *
     57  */
     58 
     59 #include <string.h>
     60 #include <openssl/err.h>
     61 #include "str_locl.h"
     62 
     63 /* The memory store is currently highly experimental.  It's meant to become
     64    a base store used by other stores for internal caching (for full caching
     65    support, aging needs to be added).
     66 
     67    The database use is meant to support as much attribute association as
     68    possible, while providing for as small search ranges as possible.
     69    This is currently provided for by sorting the entries by numbers that
     70    are composed of bits set at the positions indicated by attribute type
     71    codes.  This provides for ranges determined by the highest attribute
     72    type code value.  A better idea might be to sort by values computed
     73    from the range of attributes associated with the object (basically,
     74    the difference between the highest and lowest attribute type code)
     75    and it's distance from a base (basically, the lowest associated
     76    attribute type code).
     77 */
     78 
     79 struct mem_object_data_st
     80 	{
     81 	STORE_OBJECT *object;
     82 	STORE_ATTR_INFO *attr_info;
     83 	int references;
     84 	};
     85 
     86 struct mem_data_st
     87 	{
     88 	STACK *data;		/* A stack of mem_object_data_st,
     89 				   sorted with STORE_ATTR_INFO_compare(). */
     90 	unsigned int compute_components : 1; /* Currently unused, but can
     91 						be used to add attributes
     92 						from parts of the data. */
     93 	};
     94 
     95 struct mem_ctx_st
     96 	{
     97 	int type;		/* The type we're searching for */
     98 	STACK *search_attributes; /* Sets of attributes to search for.
     99 				     Each element is a STORE_ATTR_INFO. */
    100 	int search_index;	/* which of the search attributes we found a match
    101 				   for, -1 when we still haven't found any */
    102 	int index;		/* -1 as long as we're searching for the first */
    103 	};
    104 
    105 static int mem_init(STORE *s);
    106 static void mem_clean(STORE *s);
    107 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
    108 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    109 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
    110 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    111 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
    112 	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
    113 	OPENSSL_ITEM parameters[]);
    114 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
    115 	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
    116 	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
    117 	OPENSSL_ITEM parameters[]);
    118 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
    119 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    120 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
    121 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    122 static STORE_OBJECT *mem_list_next(STORE *s, void *handle);
    123 static int mem_list_end(STORE *s, void *handle);
    124 static int mem_list_endp(STORE *s, void *handle);
    125 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
    126 	OPENSSL_ITEM parameters[]);
    127 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
    128 	OPENSSL_ITEM parameters[]);
    129 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void));
    130 
    131 static STORE_METHOD store_memory =
    132 	{
    133 	"OpenSSL memory store interface",
    134 	mem_init,
    135 	mem_clean,
    136 	mem_generate,
    137 	mem_get,
    138 	mem_store,
    139 	mem_modify,
    140 	NULL, /* revoke */
    141 	mem_delete,
    142 	mem_list_start,
    143 	mem_list_next,
    144 	mem_list_end,
    145 	mem_list_endp,
    146 	NULL, /* update */
    147 	mem_lock,
    148 	mem_unlock,
    149 	mem_ctrl
    150 	};
    151 
    152 const STORE_METHOD *STORE_Memory(void)
    153 	{
    154 	return &store_memory;
    155 	}
    156 
    157 static int mem_init(STORE *s)
    158 	{
    159 	return 1;
    160 	}
    161 
    162 static void mem_clean(STORE *s)
    163 	{
    164 	return;
    165 	}
    166 
    167 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
    168 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    169 	{
    170 	STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED);
    171 	return 0;
    172 	}
    173 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
    174 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    175 	{
    176 	void *context = mem_list_start(s, type, attributes, parameters);
    177 
    178 	if (context)
    179 		{
    180 		STORE_OBJECT *object = mem_list_next(s, context);
    181 
    182 		if (mem_list_end(s, context))
    183 			return object;
    184 		}
    185 	return NULL;
    186 	}
    187 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
    188 	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
    189 	OPENSSL_ITEM parameters[])
    190 	{
    191 	STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED);
    192 	return 0;
    193 	}
    194 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
    195 	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
    196 	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
    197 	OPENSSL_ITEM parameters[])
    198 	{
    199 	STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED);
    200 	return 0;
    201 	}
    202 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
    203 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    204 	{
    205 	STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED);
    206 	return 0;
    207 	}
    208 
    209 /* The list functions may be the hardest to understand.  Basically,
    210    mem_list_start compiles a stack of attribute info elements, and
    211    puts that stack into the context to be returned.  mem_list_next
    212    will then find the first matching element in the store, and then
    213    walk all the way to the end of the store (since any combination
    214    of attribute bits above the starting point may match the searched
    215    for bit pattern...). */
    216 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
    217 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    218 	{
    219 	struct mem_ctx_st *context =
    220 		(struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st));
    221 	void *attribute_context = NULL;
    222 	STORE_ATTR_INFO *attrs = NULL;
    223 
    224 	if (!context)
    225 		{
    226 		STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE);
    227 		return 0;
    228 		}
    229 	memset(context, 0, sizeof(struct mem_ctx_st));
    230 
    231 	attribute_context = STORE_parse_attrs_start(attributes);
    232 	if (!attribute_context)
    233 		{
    234 		STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB);
    235 		goto err;
    236 		}
    237 
    238 	while((attrs = STORE_parse_attrs_next(attribute_context)))
    239 		{
    240 		if (context->search_attributes == NULL)
    241 			{
    242 			context->search_attributes =
    243 				sk_new((int (*)(const char * const *, const char * const *))STORE_ATTR_INFO_compare);
    244 			if (!context->search_attributes)
    245 				{
    246 				STOREerr(STORE_F_MEM_LIST_START,
    247 					ERR_R_MALLOC_FAILURE);
    248 				goto err;
    249 				}
    250 			}
    251 		sk_push(context->search_attributes,(char *)attrs);
    252 		}
    253 	if (!STORE_parse_attrs_endp(attribute_context))
    254 		goto err;
    255 	STORE_parse_attrs_end(attribute_context);
    256 	context->search_index = -1;
    257 	context->index = -1;
    258 	return context;
    259  err:
    260 	if (attribute_context) STORE_parse_attrs_end(attribute_context);
    261 	mem_list_end(s, context);
    262 	return NULL;
    263 	}
    264 static STORE_OBJECT *mem_list_next(STORE *s, void *handle)
    265 	{
    266 	int i;
    267 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
    268 	struct mem_object_data_st key = { 0, 0, 1 };
    269 	struct mem_data_st *store =
    270 		(struct mem_data_st *)STORE_get_ex_data(s, 1);
    271 	int srch;
    272 	int cres = 0;
    273 
    274 	if (!context)
    275 		{
    276 		STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
    277 		return NULL;
    278 		}
    279 	if (!store)
    280 		{
    281 		STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE);
    282 		return NULL;
    283 		}
    284 
    285 	if (context->search_index == -1)
    286 		{
    287 		for (i = 0; i < sk_num(context->search_attributes); i++)
    288 			{
    289 			key.attr_info =
    290 				(STORE_ATTR_INFO *)sk_value(context->search_attributes, i);
    291 			srch = sk_find_ex(store->data, (char *)&key);
    292 
    293 			if (srch >= 0)
    294 				{
    295 				context->search_index = srch;
    296 				break;
    297 				}
    298 			}
    299 		}
    300 	if (context->search_index < 0)
    301 		return NULL;
    302 
    303 	key.attr_info =
    304 		(STORE_ATTR_INFO *)sk_value(context->search_attributes,
    305 			context->search_index);
    306 	for(srch = context->search_index;
    307 	    srch < sk_num(store->data)
    308 		    && STORE_ATTR_INFO_in_range(key.attr_info,
    309 			    (STORE_ATTR_INFO *)sk_value(store->data, srch))
    310 		    && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
    311 				 (STORE_ATTR_INFO *)sk_value(store->data, srch)));
    312 	    srch++)
    313 		;
    314 
    315 	context->search_index = srch;
    316 	if (cres)
    317 		return ((struct mem_object_data_st *)sk_value(store->data,
    318 				srch))->object;
    319 	return NULL;
    320 	}
    321 static int mem_list_end(STORE *s, void *handle)
    322 	{
    323 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
    324 
    325 	if (!context)
    326 		{
    327 		STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER);
    328 		return 0;
    329 		}
    330 	if (context && context->search_attributes)
    331 		sk_free(context->search_attributes);
    332 	if (context) OPENSSL_free(context);
    333 	return 1;
    334 	}
    335 static int mem_list_endp(STORE *s, void *handle)
    336 	{
    337 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
    338 
    339 	if (!context
    340 		|| context->search_index == sk_num(context->search_attributes))
    341 		return 1;
    342 	return 0;
    343 	}
    344 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
    345 	OPENSSL_ITEM parameters[])
    346 	{
    347 	return 1;
    348 	}
    349 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
    350 	OPENSSL_ITEM parameters[])
    351 	{
    352 	return 1;
    353 	}
    354 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void))
    355 	{
    356 	return 1;
    357 	}
    358