1295009Sjkim/* crypto/store/str_mem.c */ 2280297Sjkim/* 3280297Sjkim * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4280297Sjkim * 2003. 5160814Ssimon */ 6160814Ssimon/* ==================================================================== 7160814Ssimon * Copyright (c) 2003 The OpenSSL Project. All rights reserved. 8160814Ssimon * 9160814Ssimon * Redistribution and use in source and binary forms, with or without 10160814Ssimon * modification, are permitted provided that the following conditions 11160814Ssimon * are met: 12160814Ssimon * 13160814Ssimon * 1. Redistributions of source code must retain the above copyright 14280297Sjkim * notice, this list of conditions and the following disclaimer. 15160814Ssimon * 16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 17160814Ssimon * notice, this list of conditions and the following disclaimer in 18160814Ssimon * the documentation and/or other materials provided with the 19160814Ssimon * distribution. 20160814Ssimon * 21160814Ssimon * 3. All advertising materials mentioning features or use of this 22160814Ssimon * software must display the following acknowledgment: 23160814Ssimon * "This product includes software developed by the OpenSSL Project 24160814Ssimon * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 25160814Ssimon * 26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27160814Ssimon * endorse or promote products derived from this software without 28160814Ssimon * prior written permission. For written permission, please contact 29160814Ssimon * openssl-core@openssl.org. 30160814Ssimon * 31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 32160814Ssimon * nor may "OpenSSL" appear in their names without prior written 33160814Ssimon * permission of the OpenSSL Project. 34160814Ssimon * 35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 36160814Ssimon * acknowledgment: 37160814Ssimon * "This product includes software developed by the OpenSSL Project 38160814Ssimon * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 39160814Ssimon * 40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 52160814Ssimon * ==================================================================== 53160814Ssimon * 54160814Ssimon * This product includes cryptographic software written by Eric Young 55160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 56160814Ssimon * Hudson (tjh@cryptsoft.com). 57160814Ssimon * 58160814Ssimon */ 59160814Ssimon 60160814Ssimon#include <string.h> 61160814Ssimon#include <openssl/err.h> 62160814Ssimon#include "str_locl.h" 63160814Ssimon 64280297Sjkim/* 65280297Sjkim * The memory store is currently highly experimental. It's meant to become a 66280297Sjkim * base store used by other stores for internal caching (for full caching 67280297Sjkim * support, aging needs to be added). 68280297Sjkim * 69280297Sjkim * The database use is meant to support as much attribute association as 70280297Sjkim * possible, while providing for as small search ranges as possible. This is 71280297Sjkim * currently provided for by sorting the entries by numbers that are composed 72280297Sjkim * of bits set at the positions indicated by attribute type codes. This 73280297Sjkim * provides for ranges determined by the highest attribute type code value. 74280297Sjkim * A better idea might be to sort by values computed from the range of 75280297Sjkim * attributes associated with the object (basically, the difference between 76280297Sjkim * the highest and lowest attribute type code) and it's distance from a base 77280297Sjkim * (basically, the lowest associated attribute type code). 78280297Sjkim */ 79160814Ssimon 80280297Sjkimtypedef struct mem_object_data_st { 81280297Sjkim STORE_OBJECT *object; 82280297Sjkim STORE_ATTR_INFO *attr_info; 83280297Sjkim int references; 84280297Sjkim} MEM_OBJECT_DATA; 85160814Ssimon 86238405SjkimDECLARE_STACK_OF(MEM_OBJECT_DATA) 87280297Sjkimstruct mem_data_st { 88280297Sjkim /* 89280297Sjkim * sorted with 90280297Sjkim * STORE_ATTR_INFO_compare(). 91280297Sjkim */ 92280297Sjkim STACK_OF(MEM_OBJECT_DATA) *data; 93280297Sjkim /* 94280297Sjkim * Currently unused, but can 95280297Sjkim * be used to add attributes 96280297Sjkim * from parts of the data. 97280297Sjkim */ 98280297Sjkim unsigned int compute_components:1; 99280297Sjkim}; 100160814Ssimon 101238405SjkimDECLARE_STACK_OF(STORE_ATTR_INFO) 102280297Sjkimstruct mem_ctx_st { 103280297Sjkim /* The type we're searching for */ 104280297Sjkim int type; 105280297Sjkim /* 106280297Sjkim * Sets of 107280297Sjkim * attributes to search for. Each 108280297Sjkim * element is a STORE_ATTR_INFO. 109280297Sjkim */ 110280297Sjkim STACK_OF(STORE_ATTR_INFO) *search_attributes; 111280297Sjkim /* 112280297Sjkim * which of the search attributes we 113280297Sjkim * found a match for, -1 when we still 114280297Sjkim * haven't found any 115280297Sjkim */ 116280297Sjkim int search_index; 117280297Sjkim /* -1 as long as we're searching for the first */ 118280297Sjkim int index; 119280297Sjkim}; 120160814Ssimon 121160814Ssimonstatic int mem_init(STORE *s); 122160814Ssimonstatic void mem_clean(STORE *s); 123160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 124280297Sjkim OPENSSL_ITEM attributes[], 125280297Sjkim OPENSSL_ITEM parameters[]); 126160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 127280297Sjkim OPENSSL_ITEM attributes[], 128280297Sjkim OPENSSL_ITEM parameters[]); 129280297Sjkimstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, STORE_OBJECT *data, 130280297Sjkim OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 131160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 132280297Sjkim OPENSSL_ITEM search_attributes[], 133280297Sjkim OPENSSL_ITEM add_attributes[], 134280297Sjkim OPENSSL_ITEM modify_attributes[], 135280297Sjkim OPENSSL_ITEM delete_attributes[], 136280297Sjkim OPENSSL_ITEM parameters[]); 137160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 138280297Sjkim OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 139160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 140280297Sjkim OPENSSL_ITEM attributes[], 141280297Sjkim OPENSSL_ITEM parameters[]); 142160814Ssimonstatic STORE_OBJECT *mem_list_next(STORE *s, void *handle); 143160814Ssimonstatic int mem_list_end(STORE *s, void *handle); 144160814Ssimonstatic int mem_list_endp(STORE *s, void *handle); 145160814Ssimonstatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 146280297Sjkim OPENSSL_ITEM parameters[]); 147160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 148280297Sjkim OPENSSL_ITEM parameters[]); 149280297Sjkimstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)); 150160814Ssimon 151280297Sjkimstatic STORE_METHOD store_memory = { 152280297Sjkim "OpenSSL memory store interface", 153280297Sjkim mem_init, 154280297Sjkim mem_clean, 155280297Sjkim mem_generate, 156280297Sjkim mem_get, 157280297Sjkim mem_store, 158280297Sjkim mem_modify, 159280297Sjkim NULL, /* revoke */ 160280297Sjkim mem_delete, 161280297Sjkim mem_list_start, 162280297Sjkim mem_list_next, 163280297Sjkim mem_list_end, 164280297Sjkim mem_list_endp, 165280297Sjkim NULL, /* update */ 166280297Sjkim mem_lock, 167280297Sjkim mem_unlock, 168280297Sjkim mem_ctrl 169280297Sjkim}; 170160814Ssimon 171160814Ssimonconst STORE_METHOD *STORE_Memory(void) 172280297Sjkim{ 173280297Sjkim return &store_memory; 174280297Sjkim} 175160814Ssimon 176160814Ssimonstatic int mem_init(STORE *s) 177280297Sjkim{ 178280297Sjkim return 1; 179280297Sjkim} 180160814Ssimon 181160814Ssimonstatic void mem_clean(STORE *s) 182280297Sjkim{ 183280297Sjkim return; 184280297Sjkim} 185160814Ssimon 186160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 187280297Sjkim OPENSSL_ITEM attributes[], 188280297Sjkim OPENSSL_ITEM parameters[]) 189280297Sjkim{ 190280297Sjkim STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); 191280297Sjkim return 0; 192280297Sjkim} 193280297Sjkim 194160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 195280297Sjkim OPENSSL_ITEM attributes[], 196280297Sjkim OPENSSL_ITEM parameters[]) 197280297Sjkim{ 198280297Sjkim void *context = mem_list_start(s, type, attributes, parameters); 199160814Ssimon 200280297Sjkim if (context) { 201280297Sjkim STORE_OBJECT *object = mem_list_next(s, context); 202280297Sjkim 203280297Sjkim if (mem_list_end(s, context)) 204280297Sjkim return object; 205280297Sjkim } 206280297Sjkim return NULL; 207280297Sjkim} 208280297Sjkim 209160814Ssimonstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, 210280297Sjkim STORE_OBJECT *data, OPENSSL_ITEM attributes[], 211280297Sjkim OPENSSL_ITEM parameters[]) 212280297Sjkim{ 213280297Sjkim STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); 214280297Sjkim return 0; 215280297Sjkim} 216280297Sjkim 217160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 218280297Sjkim OPENSSL_ITEM search_attributes[], 219280297Sjkim OPENSSL_ITEM add_attributes[], 220280297Sjkim OPENSSL_ITEM modify_attributes[], 221280297Sjkim OPENSSL_ITEM delete_attributes[], 222280297Sjkim OPENSSL_ITEM parameters[]) 223280297Sjkim{ 224280297Sjkim STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); 225280297Sjkim return 0; 226280297Sjkim} 227280297Sjkim 228160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 229280297Sjkim OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) 230280297Sjkim{ 231280297Sjkim STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); 232280297Sjkim return 0; 233280297Sjkim} 234160814Ssimon 235280297Sjkim/* 236280297Sjkim * The list functions may be the hardest to understand. Basically, 237280297Sjkim * mem_list_start compiles a stack of attribute info elements, and puts that 238280297Sjkim * stack into the context to be returned. mem_list_next will then find the 239280297Sjkim * first matching element in the store, and then walk all the way to the end 240280297Sjkim * of the store (since any combination of attribute bits above the starting 241280297Sjkim * point may match the searched for bit pattern...). 242280297Sjkim */ 243160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 244280297Sjkim OPENSSL_ITEM attributes[], 245280297Sjkim OPENSSL_ITEM parameters[]) 246280297Sjkim{ 247280297Sjkim struct mem_ctx_st *context = 248280297Sjkim (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); 249280297Sjkim void *attribute_context = NULL; 250280297Sjkim STORE_ATTR_INFO *attrs = NULL; 251160814Ssimon 252280297Sjkim if (!context) { 253280297Sjkim STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 254280297Sjkim return 0; 255280297Sjkim } 256280297Sjkim memset(context, 0, sizeof(struct mem_ctx_st)); 257160814Ssimon 258280297Sjkim attribute_context = STORE_parse_attrs_start(attributes); 259280297Sjkim if (!attribute_context) { 260280297Sjkim STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); 261280297Sjkim goto err; 262280297Sjkim } 263160814Ssimon 264280297Sjkim while ((attrs = STORE_parse_attrs_next(attribute_context))) { 265280297Sjkim if (context->search_attributes == NULL) { 266280297Sjkim context->search_attributes = 267280297Sjkim sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare); 268280297Sjkim if (!context->search_attributes) { 269280297Sjkim STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 270280297Sjkim goto err; 271280297Sjkim } 272280297Sjkim } 273280297Sjkim sk_STORE_ATTR_INFO_push(context->search_attributes, attrs); 274280297Sjkim } 275280297Sjkim if (!STORE_parse_attrs_endp(attribute_context)) 276280297Sjkim goto err; 277280297Sjkim STORE_parse_attrs_end(attribute_context); 278280297Sjkim context->search_index = -1; 279280297Sjkim context->index = -1; 280280297Sjkim return context; 281160814Ssimon err: 282280297Sjkim if (attribute_context) 283280297Sjkim STORE_parse_attrs_end(attribute_context); 284280297Sjkim mem_list_end(s, context); 285280297Sjkim return NULL; 286280297Sjkim} 287280297Sjkim 288160814Ssimonstatic STORE_OBJECT *mem_list_next(STORE *s, void *handle) 289280297Sjkim{ 290280297Sjkim int i; 291280297Sjkim struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 292280297Sjkim struct mem_object_data_st key = { 0, 0, 1 }; 293280297Sjkim struct mem_data_st *store = (struct mem_data_st *)STORE_get_ex_data(s, 1); 294280297Sjkim int srch; 295280297Sjkim int cres = 0; 296160814Ssimon 297280297Sjkim if (!context) { 298280297Sjkim STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); 299280297Sjkim return NULL; 300280297Sjkim } 301280297Sjkim if (!store) { 302280297Sjkim STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); 303280297Sjkim return NULL; 304280297Sjkim } 305160814Ssimon 306280297Sjkim if (context->search_index == -1) { 307280297Sjkim for (i = 0; 308280297Sjkim i < sk_STORE_ATTR_INFO_num(context->search_attributes); i++) { 309280297Sjkim key.attr_info 310280297Sjkim = sk_STORE_ATTR_INFO_value(context->search_attributes, i); 311280297Sjkim srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key); 312160814Ssimon 313280297Sjkim if (srch >= 0) { 314280297Sjkim context->search_index = srch; 315280297Sjkim break; 316280297Sjkim } 317280297Sjkim } 318280297Sjkim } 319280297Sjkim if (context->search_index < 0) 320280297Sjkim return NULL; 321160814Ssimon 322280297Sjkim key.attr_info = 323280297Sjkim sk_STORE_ATTR_INFO_value(context->search_attributes, 324280297Sjkim context->search_index); 325280297Sjkim for (srch = context->search_index; 326280297Sjkim srch < sk_MEM_OBJECT_DATA_num(store->data) 327280297Sjkim && STORE_ATTR_INFO_in_range(key.attr_info, 328280297Sjkim sk_MEM_OBJECT_DATA_value(store->data, 329280297Sjkim srch)->attr_info) 330280297Sjkim && !(cres = 331280297Sjkim STORE_ATTR_INFO_in_ex(key.attr_info, 332280297Sjkim sk_MEM_OBJECT_DATA_value(store->data, 333280297Sjkim srch)->attr_info)); 334280297Sjkim srch++) ; 335280297Sjkim 336280297Sjkim context->search_index = srch; 337280297Sjkim if (cres) 338280297Sjkim return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object; 339280297Sjkim return NULL; 340280297Sjkim} 341280297Sjkim 342160814Ssimonstatic int mem_list_end(STORE *s, void *handle) 343280297Sjkim{ 344280297Sjkim struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 345160814Ssimon 346280297Sjkim if (!context) { 347280297Sjkim STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); 348280297Sjkim return 0; 349280297Sjkim } 350280297Sjkim if (context && context->search_attributes) 351280297Sjkim sk_STORE_ATTR_INFO_free(context->search_attributes); 352280297Sjkim if (context) 353280297Sjkim OPENSSL_free(context); 354280297Sjkim return 1; 355280297Sjkim} 356280297Sjkim 357160814Ssimonstatic int mem_list_endp(STORE *s, void *handle) 358280297Sjkim{ 359280297Sjkim struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 360160814Ssimon 361280297Sjkim if (!context 362280297Sjkim || context->search_index 363280297Sjkim == sk_STORE_ATTR_INFO_num(context->search_attributes)) 364280297Sjkim return 1; 365280297Sjkim return 0; 366280297Sjkim} 367280297Sjkim 368160814Ssimonstatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 369280297Sjkim OPENSSL_ITEM parameters[]) 370280297Sjkim{ 371280297Sjkim return 1; 372280297Sjkim} 373280297Sjkim 374160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 375280297Sjkim OPENSSL_ITEM parameters[]) 376280297Sjkim{ 377280297Sjkim return 1; 378280297Sjkim} 379280297Sjkim 380280297Sjkimstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)) 381280297Sjkim{ 382280297Sjkim return 1; 383280297Sjkim} 384