| OLD | NEW |
| (Empty) |
| 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 | |
| 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_in
fo) | |
| 318 && !(cres = STORE_ATTR_INFO_in_ex(key.attr_info, | |
| 319 sk_MEM_OBJECT_DATA_value(store->data, srch)->at
tr_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 } | |
| OLD | NEW |