7480de00292bb98b582a0527e03bf0da7949eb36
[openssl.git] / crypto / store / str_mem.c
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 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)());
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_STORE, 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 nuderstand.  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                     && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
309                                  (STORE_ATTR_INFO *)sk_value(store->data, srch)));
310             srch++)
311                 ;
312
313         context->search_index = srch;
314         if (cres)
315                 return ((struct mem_object_data_st *)sk_value(store->data,
316                                 srch))->object;
317         return NULL;
318         }
319 static int mem_list_end(STORE *s, void *handle)
320         {
321         struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
322
323         if (!context)
324                 {
325                 STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
326                 return 0;
327                 }
328         if (context && context->search_attributes)
329                 sk_free(context->search_attributes);
330         if (context) OPENSSL_free(context);
331         return 1;
332         }
333 static int mem_list_endp(STORE *s, void *handle)
334         {
335         struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
336
337         if (!context
338                 || context->search_index == sk_num(context->search_attributes))
339                 return 1;
340         return 0;
341         }
342 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[],
343         OPENSSL_ITEM parameters[])
344         {
345         return 1;
346         }
347 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[],
348         OPENSSL_ITEM parameters[])
349         {
350         return 1;
351         }
352 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)())
353         {
354         return 1;
355         }