str_mem.c revision 296465
1/* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */ 2/* 3 * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4 * 2003. 5 */ 6/* ==================================================================== 7 * Copyright (c) 2003 The OpenSSL Project. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in 18 * the documentation and/or other materials provided with the 19 * distribution. 20 * 21 * 3. All advertising materials mentioning features or use of this 22 * software must display the following acknowledgment: 23 * "This product includes software developed by the OpenSSL Project 24 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 25 * 26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27 * endorse or promote products derived from this software without 28 * prior written permission. For written permission, please contact 29 * openssl-core@openssl.org. 30 * 31 * 5. Products derived from this software may not be called "OpenSSL" 32 * nor may "OpenSSL" appear in their names without prior written 33 * permission of the OpenSSL Project. 34 * 35 * 6. Redistributions of any form whatsoever must retain the following 36 * acknowledgment: 37 * "This product includes software developed by the OpenSSL Project 38 * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51 * OF THE POSSIBILITY OF SUCH DAMAGE. 52 * ==================================================================== 53 * 54 * This product includes cryptographic software written by Eric Young 55 * (eay@cryptsoft.com). This product includes software written by Tim 56 * Hudson (tjh@cryptsoft.com). 57 * 58 */ 59 60#include <string.h> 61#include <openssl/err.h> 62#include "str_locl.h" 63 64/* 65 * The memory store is currently highly experimental. It's meant to become a 66 * base store used by other stores for internal caching (for full caching 67 * support, aging needs to be added). 68 * 69 * The database use is meant to support as much attribute association as 70 * possible, while providing for as small search ranges as possible. This is 71 * currently provided for by sorting the entries by numbers that are composed 72 * of bits set at the positions indicated by attribute type codes. This 73 * provides for ranges determined by the highest attribute type code value. 74 * A better idea might be to sort by values computed from the range of 75 * attributes associated with the object (basically, the difference between 76 * the highest and lowest attribute type code) and it's distance from a base 77 * (basically, the lowest associated attribute type code). 78 */ 79 80struct mem_object_data_st { 81 STORE_OBJECT *object; 82 STORE_ATTR_INFO *attr_info; 83 int references; 84}; 85 86struct mem_data_st { 87 /* 88 * A stack of mem_object_data_st, 89 * sorted with STORE_ATTR_INFO_compare(). 90 */ 91 STACK *data; 92 /* 93 * Currently unused, but can be used to add attributes from parts of the 94 * data. 95 */ 96 unsigned int compute_components:1; 97}; 98 99struct mem_ctx_st { 100 /* The type we're searching for */ 101 int type; 102 /* 103 * Sets of attributes to search for. 104 * Each element is a STORE_ATTR_INFO. 105 */ 106 STACK *search_attributes; 107 /* 108 * which of the search attributes we found a match 109 * for, -1 when we still haven't found any 110 */ 111 int search_index; 112 /* -1 as long as we're searching for the first */ 113 int index; 114}; 115 116static int mem_init(STORE *s); 117static void mem_clean(STORE *s); 118static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 119 OPENSSL_ITEM attributes[], 120 OPENSSL_ITEM parameters[]); 121static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 122 OPENSSL_ITEM attributes[], 123 OPENSSL_ITEM parameters[]); 124static int mem_store(STORE *s, STORE_OBJECT_TYPES type, STORE_OBJECT *data, 125 OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 126static int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 127 OPENSSL_ITEM search_attributes[], 128 OPENSSL_ITEM add_attributes[], 129 OPENSSL_ITEM modify_attributes[], 130 OPENSSL_ITEM delete_attributes[], 131 OPENSSL_ITEM parameters[]); 132static int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 133 OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 134static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 135 OPENSSL_ITEM attributes[], 136 OPENSSL_ITEM parameters[]); 137static STORE_OBJECT *mem_list_next(STORE *s, void *handle); 138static int mem_list_end(STORE *s, void *handle); 139static int mem_list_endp(STORE *s, void *handle); 140static int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 141 OPENSSL_ITEM parameters[]); 142static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 143 OPENSSL_ITEM parameters[]); 144static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)); 145 146static STORE_METHOD store_memory = { 147 "OpenSSL memory store interface", 148 mem_init, 149 mem_clean, 150 mem_generate, 151 mem_get, 152 mem_store, 153 mem_modify, 154 NULL, /* revoke */ 155 mem_delete, 156 mem_list_start, 157 mem_list_next, 158 mem_list_end, 159 mem_list_endp, 160 NULL, /* update */ 161 mem_lock, 162 mem_unlock, 163 mem_ctrl 164}; 165 166const STORE_METHOD *STORE_Memory(void) 167{ 168 return &store_memory; 169} 170 171static int mem_init(STORE *s) 172{ 173 return 1; 174} 175 176static void mem_clean(STORE *s) 177{ 178 return; 179} 180 181static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 182 OPENSSL_ITEM attributes[], 183 OPENSSL_ITEM parameters[]) 184{ 185 STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); 186 return 0; 187} 188 189static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 190 OPENSSL_ITEM attributes[], 191 OPENSSL_ITEM parameters[]) 192{ 193 void *context = mem_list_start(s, type, attributes, parameters); 194 195 if (context) { 196 STORE_OBJECT *object = mem_list_next(s, context); 197 198 if (mem_list_end(s, context)) 199 return object; 200 } 201 return NULL; 202} 203 204static int mem_store(STORE *s, STORE_OBJECT_TYPES type, 205 STORE_OBJECT *data, OPENSSL_ITEM attributes[], 206 OPENSSL_ITEM parameters[]) 207{ 208 STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); 209 return 0; 210} 211 212static int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 213 OPENSSL_ITEM search_attributes[], 214 OPENSSL_ITEM add_attributes[], 215 OPENSSL_ITEM modify_attributes[], 216 OPENSSL_ITEM delete_attributes[], 217 OPENSSL_ITEM parameters[]) 218{ 219 STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); 220 return 0; 221} 222 223static int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 224 OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) 225{ 226 STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); 227 return 0; 228} 229 230/* 231 * The list functions may be the hardest to understand. Basically, 232 * mem_list_start compiles a stack of attribute info elements, and puts that 233 * stack into the context to be returned. mem_list_next will then find the 234 * first matching element in the store, and then walk all the way to the end 235 * of the store (since any combination of attribute bits above the starting 236 * point may match the searched for bit pattern...). 237 */ 238static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 239 OPENSSL_ITEM attributes[], 240 OPENSSL_ITEM parameters[]) 241{ 242 struct mem_ctx_st *context = 243 (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); 244 void *attribute_context = NULL; 245 STORE_ATTR_INFO *attrs = NULL; 246 247 if (!context) { 248 STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 249 return 0; 250 } 251 memset(context, 0, sizeof(struct mem_ctx_st)); 252 253 attribute_context = STORE_parse_attrs_start(attributes); 254 if (!attribute_context) { 255 STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); 256 goto err; 257 } 258 259 while ((attrs = STORE_parse_attrs_next(attribute_context))) { 260 if (context->search_attributes == NULL) { 261 context->search_attributes = 262 sk_new((int (*)(const char *const *, const char *const *)) 263 STORE_ATTR_INFO_compare); 264 if (!context->search_attributes) { 265 STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 266 goto err; 267 } 268 } 269 sk_push(context->search_attributes, (char *)attrs); 270 } 271 if (!STORE_parse_attrs_endp(attribute_context)) 272 goto err; 273 STORE_parse_attrs_end(attribute_context); 274 context->search_index = -1; 275 context->index = -1; 276 return context; 277 err: 278 if (attribute_context) 279 STORE_parse_attrs_end(attribute_context); 280 mem_list_end(s, context); 281 return NULL; 282} 283 284static STORE_OBJECT *mem_list_next(STORE *s, void *handle) 285{ 286 int i; 287 struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 288 struct mem_object_data_st key = { 0, 0, 1 }; 289 struct mem_data_st *store = (struct mem_data_st *)STORE_get_ex_data(s, 1); 290 int srch; 291 int cres = 0; 292 293 if (!context) { 294 STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); 295 return NULL; 296 } 297 if (!store) { 298 STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); 299 return NULL; 300 } 301 302 if (context->search_index == -1) { 303 for (i = 0; i < sk_num(context->search_attributes); i++) { 304 key.attr_info = 305 (STORE_ATTR_INFO *)sk_value(context->search_attributes, i); 306 srch = sk_find_ex(store->data, (char *)&key); 307 308 if (srch >= 0) { 309 context->search_index = srch; 310 break; 311 } 312 } 313 } 314 if (context->search_index < 0) 315 return NULL; 316 317 key.attr_info = 318 (STORE_ATTR_INFO *)sk_value(context->search_attributes, 319 context->search_index); 320 for (srch = context->search_index; srch < sk_num(store->data) 321 && STORE_ATTR_INFO_in_range(key.attr_info, 322 (STORE_ATTR_INFO *)sk_value(store->data, 323 srch)) 324 && !(cres = 325 STORE_ATTR_INFO_in_ex(key.attr_info, 326 (STORE_ATTR_INFO *)sk_value(store->data, 327 srch))); 328 srch++) ; 329 330 context->search_index = srch; 331 if (cres) 332 return ((struct mem_object_data_st *)sk_value(store->data, 333 srch))->object; 334 return NULL; 335} 336 337static int mem_list_end(STORE *s, void *handle) 338{ 339 struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 340 341 if (!context) { 342 STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); 343 return 0; 344 } 345 if (context && context->search_attributes) 346 sk_free(context->search_attributes); 347 if (context) 348 OPENSSL_free(context); 349 return 1; 350} 351 352static int mem_list_endp(STORE *s, void *handle) 353{ 354 struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 355 356 if (!context 357 || context->search_index == sk_num(context->search_attributes)) 358 return 1; 359 return 0; 360} 361 362static int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 363 OPENSSL_ITEM parameters[]) 364{ 365 return 1; 366} 367 368static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 369 OPENSSL_ITEM parameters[]) 370{ 371 return 1; 372} 373 374static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)) 375{ 376 return 1; 377} 378