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 typedef struct mem_object_data_st
     80 	{
     81 	STORE_OBJECT *object;
     82 	STORE_ATTR_INFO *attr_info;
     83 	int references;
     84 	} MEM_OBJECT_DATA;
     85 
     86 DECLARE_STACK_OF(MEM_OBJECT_DATA)
     87 struct mem_data_st
     88 	{
     89 	STACK_OF(MEM_OBJECT_DATA) *data; /* sorted with
     90 					  * STORE_ATTR_INFO_compare(). */
     91 	unsigned int compute_components : 1; /* Currently unused, but can
     92 						be used to add attributes
     93 						from parts of the data. */
     94 	};
     95 
     96 DECLARE_STACK_OF(STORE_ATTR_INFO)
     97 struct mem_ctx_st
     98 	{
     99 	int type;		/* The type we're searching for */
    100 	STACK_OF(STORE_ATTR_INFO) *search_attributes; /* Sets of
    101 				     attributes to search for.  Each
    102 				     element is a STORE_ATTR_INFO. */
    103 	int search_index;	/* which of the search attributes we
    104 				   found a match for, -1 when we still
    105 				   haven't found any */
    106 	int index;		/* -1 as long as we're searching for
    107                                     the first */
    108 	};
    109 
    110 static int mem_init(STORE *s);
    111 static void mem_clean(STORE *s);
    112 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
    113 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    114 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
    115 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    116 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
    117 	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
    118 	OPENSSL_ITEM parameters[]);
    119 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
    120 	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
    121 	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
    122 	OPENSSL_ITEM parameters[]);
    123 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
    124 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    125 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
    126 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]);
    127 static STORE_OBJECT *mem_list_next(STORE *s, void *handle);
    128 static int mem_list_end(STORE *s, void *handle);
    129 static int mem_list_endp(STORE *s, void *handle);
    130 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
    131 	OPENSSL_ITEM parameters[]);
    132 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
    133 	OPENSSL_ITEM parameters[]);
    134 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void));
    135 
    136 static STORE_METHOD store_memory =
    137 	{
    138 	"OpenSSL memory store interface",
    139 	mem_init,
    140 	mem_clean,
    141 	mem_generate,
    142 	mem_get,
    143 	mem_store,
    144 	mem_modify,
    145 	NULL, /* revoke */
    146 	mem_delete,
    147 	mem_list_start,
    148 	mem_list_next,
    149 	mem_list_end,
    150 	mem_list_endp,
    151 	NULL, /* update */
    152 	mem_lock,
    153 	mem_unlock,
    154 	mem_ctrl
    155 	};
    156 
    157 const STORE_METHOD *STORE_Memory(void)
    158 	{
    159 	return &store_memory;
    160 	}
    161 
    162 static int mem_init(STORE *s)
    163 	{
    164 	return 1;
    165 	}
    166 
    167 static void mem_clean(STORE *s)
    168 	{
    169 	return;
    170 	}
    171 
    172 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
    173 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    174 	{
    175 	STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED);
    176 	return 0;
    177 	}
    178 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
    179 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    180 	{
    181 	void *context = mem_list_start(s, type, attributes, parameters);
    182 
    183 	if (context)
    184 		{
    185 		STORE_OBJECT *object = mem_list_next(s, context);
    186 
    187 		if (mem_list_end(s, context))
    188 			return object;
    189 		}
    190 	return NULL;
    191 	}
    192 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
    193 	STORE_OBJECT *data, OPENSSL_ITEM attributes[],
    194 	OPENSSL_ITEM parameters[])
    195 	{
    196 	STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED);
    197 	return 0;
    198 	}
    199 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
    200 	OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
    201 	OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[],
    202 	OPENSSL_ITEM parameters[])
    203 	{
    204 	STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED);
    205 	return 0;
    206 	}
    207 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
    208 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    209 	{
    210 	STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED);
    211 	return 0;
    212 	}
    213 
    214 /* The list functions may be the hardest to understand.  Basically,
    215    mem_list_start compiles a stack of attribute info elements, and
    216    puts that stack into the context to be returned.  mem_list_next
    217    will then find the first matching element in the store, and then
    218    walk all the way to the end of the store (since any combination
    219    of attribute bits above the starting point may match the searched
    220    for bit pattern...). */
    221 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
    222 	OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[])
    223 	{
    224 	struct mem_ctx_st *context =
    225 		(struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st));
    226 	void *attribute_context = NULL;
    227 	STORE_ATTR_INFO *attrs = NULL;
    228 
    229 	if (!context)
    230 		{
    231 		STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE);
    232 		return 0;
    233 		}
    234 	memset(context, 0, sizeof(struct mem_ctx_st));
    235 
    236 	attribute_context = STORE_parse_attrs_start(attributes);
    237 	if (!attribute_context)
    238 		{
    239 		STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB);
    240 		goto err;
    241 		}
    242 
    243 	while((attrs = STORE_parse_attrs_next(attribute_context)))
    244 		{
    245 		if (context->search_attributes == NULL)
    246 			{
    247 			context->search_attributes =
    248 				sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare);
    249 			if (!context->search_attributes)
    250 				{
    251 				STOREerr(STORE_F_MEM_LIST_START,
    252 					ERR_R_MALLOC_FAILURE);
    253 				goto err;
    254 				}
    255 			}
    256 		sk_STORE_ATTR_INFO_push(context->search_attributes,attrs);
    257 		}
    258 	if (!STORE_parse_attrs_endp(attribute_context))
    259 		goto err;
    260 	STORE_parse_attrs_end(attribute_context);
    261 	context->search_index = -1;
    262 	context->index = -1;
    263 	return context;
    264  err:
    265 	if (attribute_context) STORE_parse_attrs_end(attribute_context);
    266 	mem_list_end(s, context);
    267 	return NULL;
    268 	}
    269 static STORE_OBJECT *mem_list_next(STORE *s, void *handle)
    270 	{
    271 	int i;
    272 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
    273 	struct mem_object_data_st key = { 0, 0, 1 };
    274 	struct mem_data_st *store =
    275 		(struct mem_data_st *)STORE_get_ex_data(s, 1);
    276 	int srch;
    277 	int cres = 0;
    278 
    279 	if (!context)
    280 		{
    281 		STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
    282 		return NULL;
    283 		}
    284 	if (!store)
    285 		{
    286 		STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE);
    287 		return NULL;
    288 		}
    289 
    290 	if (context->search_index == -1)
    291 		{
    292 		for (i = 0;
    293 		     i < sk_STORE_ATTR_INFO_num(context->search_attributes);
    294 		     i++)
    295 			{
    296 			key.attr_info
    297 			  = sk_STORE_ATTR_INFO_value(context->search_attributes,
    298 						     i);
    299 			srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key);
    300 
    301 			if (srch >= 0)
    302 				{
    303 				context->search_index = srch;
    304 				break;
    305 				}
    306 			}
    307 		}
    308 	if (context->search_index < 0)
    309 		return NULL;
    310 
    311 	key.attr_info =
    312 		sk_STORE_ATTR_INFO_value(context->search_attributes,
    313 					 context->search_index);
    314 	for(srch = context->search_index;
    315 	    srch < sk_MEM_OBJECT_DATA_num(store->data)
    316 		    && STORE_ATTR_INFO_in_range(key.attr_info,
    317 			    sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info)
    318 		    && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
    319 				 sk_MEM_OBJECT_DATA_value(store->data, srch)->attr_info));
    320 	    srch++)
    321 		;
    322 
    323 	context->search_index = srch;
    324 	if (cres)
    325 		return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object;
    326 	return NULL;
    327 	}
    328 static int mem_list_end(STORE *s, void *handle)
    329 	{
    330 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
    331 
    332 	if (!context)
    333 		{
    334 		STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER);
    335 		return 0;
    336 		}
    337 	if (context && context->search_attributes)
    338 		sk_STORE_ATTR_INFO_free(context->search_attributes);
    339 	if (context) OPENSSL_free(context);
    340 	return 1;
    341 	}
    342 static int mem_list_endp(STORE *s, void *handle)
    343 	{
    344 	struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
    345 
    346 	if (!context
    347 	    || context->search_index
    348 	       == sk_STORE_ATTR_INFO_num(context->search_attributes))
    349 		return 1;
    350 	return 0;
    351 	}
    352 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
    353 	OPENSSL_ITEM parameters[])
    354 	{
    355 	return 1;
    356 	}
    357 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
    358 	OPENSSL_ITEM parameters[])
    359 	{
    360 	return 1;
    361 	}
    362 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void))
    363 	{
    364 	return 1;
    365 	}
    366