• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #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 
STORE_Memory(void)157 const STORE_METHOD *STORE_Memory(void)
158 	{
159 	return &store_memory;
160 	}
161 
mem_init(STORE * s)162 static int mem_init(STORE *s)
163 	{
164 	return 1;
165 	}
166 
mem_clean(STORE * s)167 static void mem_clean(STORE *s)
168 	{
169 	return;
170 	}
171 
mem_generate(STORE * s,STORE_OBJECT_TYPES type,OPENSSL_ITEM attributes[],OPENSSL_ITEM parameters[])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 	}
mem_get(STORE * s,STORE_OBJECT_TYPES type,OPENSSL_ITEM attributes[],OPENSSL_ITEM parameters[])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 	}
mem_store(STORE * s,STORE_OBJECT_TYPES type,STORE_OBJECT * data,OPENSSL_ITEM attributes[],OPENSSL_ITEM parameters[])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 	}
mem_modify(STORE * s,STORE_OBJECT_TYPES type,OPENSSL_ITEM search_attributes[],OPENSSL_ITEM add_attributes[],OPENSSL_ITEM modify_attributes[],OPENSSL_ITEM delete_attributes[],OPENSSL_ITEM parameters[])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 	}
mem_delete(STORE * s,STORE_OBJECT_TYPES type,OPENSSL_ITEM attributes[],OPENSSL_ITEM parameters[])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...). */
mem_list_start(STORE * s,STORE_OBJECT_TYPES type,OPENSSL_ITEM attributes[],OPENSSL_ITEM parameters[])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 	}
mem_list_next(STORE * s,void * handle)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 	}
mem_list_end(STORE * s,void * handle)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 	}
mem_list_endp(STORE * s,void * handle)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 	}
mem_lock(STORE * s,OPENSSL_ITEM attributes[],OPENSSL_ITEM parameters[])352 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
353 	OPENSSL_ITEM parameters[])
354 	{
355 	return 1;
356 	}
mem_unlock(STORE * s,OPENSSL_ITEM attributes[],OPENSSL_ITEM parameters[])357 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
358 	OPENSSL_ITEM parameters[])
359 	{
360 	return 1;
361 	}
mem_ctrl(STORE * s,int cmd,long l,void * p,void (* f)(void))362 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)(void))
363 	{
364 	return 1;
365 	}
366