a6ca31d66bf3e9fa5c4a6fbbcf07df2089146e75
[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 struct mem_object_data_st
64         {
65         STORE_OBJECT *object;
66         STORE_ATTR_INFO *attr_info;
67         int references;
68         };
69
70 struct mem_data_st
71         {
72         STACK *data;            /* A stack of mem_object_data_st,
73                                    potentially sorted with a wrapper
74                                    around STORE_ATTR_INFO_cmp(). */
75         unsigned int compute_components : 1; /* Currently unused, but can
76                                                 be used to add attributes
77                                                 from parts of the data. */
78         };
79
80 struct mem_ctx_st
81         {
82         int type;               /* The type we're searching for */
83         STACK *search_attributes; /* Sets of attributes to search for.
84                                      Each element is a STORE_ATTR_INFO. */
85         int search_index;       /* which of the search attributes we found a match
86                                    for, -1 when we still haven't found any */
87         int index;              /* -1 as long as we're searching for the first */
88         };
89
90 static int mem_init(STORE *s);
91 static void mem_clean(STORE *s);
92 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
93         OPENSSL_ITEM parameters[], OPENSSL_ITEM attributes[]);
94 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
95         OPENSSL_ITEM attributes[]);
96 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
97         STORE_OBJECT *data, OPENSSL_ITEM attributes[]);
98 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
99         OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
100         OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[]);
101 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
102         OPENSSL_ITEM attributes[]);
103 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
104         OPENSSL_ITEM attributes[]);
105 static STORE_OBJECT *mem_list_next(STORE *s, void *handle);
106 static int mem_list_end(STORE *s, void *handle);
107 static int mem_list_endp(STORE *s, void *handle);
108 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[]);
109 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[]);
110 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)());
111
112 static STORE_METHOD store_memory =
113         {
114         "OpenSSL memory store interface",
115         mem_init,
116         mem_clean,
117         mem_generate,
118         mem_get,
119         mem_store,
120         mem_modify,
121         NULL, /* revoke */
122         mem_delete,
123         mem_list_start,
124         mem_list_next,
125         mem_list_end,
126         mem_list_endp,
127         NULL, /* update */
128         mem_lock,
129         mem_unlock,
130         mem_ctrl
131         };
132
133 const STORE_METHOD *STORE_Memory(void)
134         {
135         return &store_memory;
136         }
137
138 static int mem_init(STORE *s)
139         {
140         return 1;
141         }
142
143 static void mem_clean(STORE *s)
144         {
145         return;
146         }
147
148 static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type,
149         OPENSSL_ITEM parameters[], OPENSSL_ITEM attributes[])
150         {
151         STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED);
152         return 0;
153         }
154 static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type,
155         OPENSSL_ITEM attributes[])
156         {
157         void *context = mem_list_start(s, type, attributes);
158         
159         if (context)
160                 {
161                 STORE_OBJECT *object = mem_list_next(s, context);
162
163                 if (mem_list_end(s, context))
164                         return object;
165                 }
166         return NULL;
167         }
168 static int mem_store(STORE *s, STORE_OBJECT_TYPES type,
169         STORE_OBJECT *data, OPENSSL_ITEM attributes[])
170         {
171         STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED);
172         return 0;
173         }
174 static int mem_modify(STORE *s, STORE_OBJECT_TYPES type,
175         OPENSSL_ITEM search_attributes[], OPENSSL_ITEM add_attributes[],
176         OPENSSL_ITEM modify_attributes[], OPENSSL_ITEM delete_attributes[])
177         {
178         STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED);
179         return 0;
180         }
181 static int mem_delete(STORE *s, STORE_OBJECT_TYPES type,
182         OPENSSL_ITEM attributes[])
183         {
184         STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED);
185         return 0;
186         }
187 static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type,
188         OPENSSL_ITEM attributes[])
189         {
190         struct mem_ctx_st *context =
191                 (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st));
192         void *attribute_context = NULL;
193         STORE_ATTR_INFO *attrs = NULL;
194
195         if (!context)
196                 {
197                 STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE);
198                 return 0;
199                 }
200         memset(context, 0, sizeof(struct mem_ctx_st));
201
202         attribute_context = STORE_parse_attrs_start(attributes);
203         if (!attribute_context)
204                 {
205                 STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB);
206                 goto err;
207                 }
208
209         while((attrs = STORE_parse_attrs_next(attribute_context)))
210                 {
211                 if (context->search_attributes == NULL)
212                         {
213                         context->search_attributes =
214                                 sk_new((int (*)(const char * const *, const char * const *))STORE_ATTR_INFO_compare);
215                         if (!context->search_attributes)
216                                 {
217                                 STOREerr(STORE_F_MEM_LIST_START,
218                                         ERR_R_MALLOC_FAILURE);
219                                 goto err;
220                                 }
221                         }
222                 sk_push(context->search_attributes,(char *)attrs);
223                 }
224         if (!STORE_parse_attrs_endp(attribute_context))
225                 goto err;
226         STORE_parse_attrs_end(attribute_context);
227         context->search_index = -1;
228         context->index = -1;
229         return context;
230  err:
231         if (attribute_context) STORE_parse_attrs_end(attribute_context);
232         mem_list_end(s, context);
233         return NULL;
234         }
235 static STORE_OBJECT *mem_list_next(STORE *s, void *handle)
236         {
237         int i;
238         struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
239         struct mem_object_data_st key = { 0, 0, 1 };
240         struct mem_data_st *store =
241                 (struct mem_data_st *)STORE_get_ex_data(s, 1);
242         int srch;
243         int cres = 0;
244
245         if (!context)
246                 {
247                 STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
248                 return NULL;
249                 }
250         if (!store)
251                 {
252                 STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE);
253                 return NULL;
254                 }
255
256         if (context->search_index == -1)
257                 {
258                 for (i = 0; i < sk_num(context->search_attributes); i++)
259                         {
260                         key.attr_info =
261                                 (STORE_ATTR_INFO *)sk_value(context->search_attributes, i);
262                         srch = sk_find_ex(store->data, (char *)&key);
263
264                         if (srch >= 0)
265                                 {
266                                 context->search_index = srch;
267                                 break;
268                                 }
269                         }
270                 }
271         if (context->search_index < 0)
272                 return NULL;
273         
274         key.attr_info =
275                 (STORE_ATTR_INFO *)sk_value(context->search_attributes,
276                         context->search_index);
277         for(srch = context->search_index;
278             srch < sk_num(store->data)
279                     && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info,
280                                  (STORE_ATTR_INFO *)sk_value(store->data, srch)));
281             srch++)
282                 ;
283
284         context->search_index = srch;
285         if (cres)
286                 return ((struct mem_object_data_st *)sk_value(store->data,
287                                 srch))->object;
288         return NULL;
289         }
290 static int mem_list_end(STORE *s, void *handle)
291         {
292         struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
293
294         if (!context)
295                 {
296                 STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER);
297                 return 0;
298                 }
299         if (context && context->search_attributes)
300                 sk_free(context->search_attributes);
301         if (context) OPENSSL_free(context);
302         return 1;
303         }
304 static int mem_list_endp(STORE *s, void *handle)
305         {
306         struct mem_ctx_st *context = (struct mem_ctx_st *)handle;
307
308         if (!context
309                 || context->search_index == sk_num(context->search_attributes))
310                 return 1;
311         return 0;
312         }
313 static int mem_lock(STORE *s, OPENSSL_ITEM attributes[])
314         {
315         return 1;
316         }
317 static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[])
318         {
319         return 1;
320         }
321 static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f)())
322         {
323         return 1;
324         }