1295016Sjkim/* crypto/store/str_mem.c */ 2280304Sjkim/* 3280304Sjkim * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4280304Sjkim * 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 14280304Sjkim * 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 64280304Sjkim/* 65280304Sjkim * The memory store is currently highly experimental. It's meant to become a 66280304Sjkim * base store used by other stores for internal caching (for full caching 67280304Sjkim * support, aging needs to be added). 68280304Sjkim * 69280304Sjkim * The database use is meant to support as much attribute association as 70280304Sjkim * possible, while providing for as small search ranges as possible. This is 71280304Sjkim * currently provided for by sorting the entries by numbers that are composed 72280304Sjkim * of bits set at the positions indicated by attribute type codes. This 73280304Sjkim * provides for ranges determined by the highest attribute type code value. 74280304Sjkim * A better idea might be to sort by values computed from the range of 75280304Sjkim * attributes associated with the object (basically, the difference between 76280304Sjkim * the highest and lowest attribute type code) and it's distance from a base 77280304Sjkim * (basically, the lowest associated attribute type code). 78280304Sjkim */ 79160814Ssimon 80280304Sjkimtypedef struct mem_object_data_st { 81280304Sjkim STORE_OBJECT *object; 82280304Sjkim STORE_ATTR_INFO *attr_info; 83280304Sjkim int references; 84280304Sjkim} MEM_OBJECT_DATA; 85160814Ssimon 86238405SjkimDECLARE_STACK_OF(MEM_OBJECT_DATA) 87280304Sjkimstruct mem_data_st { 88280304Sjkim /* 89280304Sjkim * sorted with 90280304Sjkim * STORE_ATTR_INFO_compare(). 91280304Sjkim */ 92280304Sjkim STACK_OF(MEM_OBJECT_DATA) *data; 93280304Sjkim /* 94280304Sjkim * Currently unused, but can 95280304Sjkim * be used to add attributes 96280304Sjkim * from parts of the data. 97280304Sjkim */ 98280304Sjkim unsigned int compute_components:1; 99280304Sjkim}; 100160814Ssimon 101238405SjkimDECLARE_STACK_OF(STORE_ATTR_INFO) 102280304Sjkimstruct mem_ctx_st { 103280304Sjkim /* The type we're searching for */ 104280304Sjkim int type; 105280304Sjkim /* 106280304Sjkim * Sets of 107280304Sjkim * attributes to search for. Each 108280304Sjkim * element is a STORE_ATTR_INFO. 109280304Sjkim */ 110280304Sjkim STACK_OF(STORE_ATTR_INFO) *search_attributes; 111280304Sjkim /* 112280304Sjkim * which of the search attributes we 113280304Sjkim * found a match for, -1 when we still 114280304Sjkim * haven't found any 115280304Sjkim */ 116280304Sjkim int search_index; 117280304Sjkim /* -1 as long as we're searching for the first */ 118280304Sjkim int index; 119280304Sjkim}; 120160814Ssimon 121160814Ssimonstatic int mem_init(STORE *s); 122160814Ssimonstatic void mem_clean(STORE *s); 123160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 124280304Sjkim OPENSSL_ITEM attributes[], 125280304Sjkim OPENSSL_ITEM parameters[]); 126160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 127280304Sjkim OPENSSL_ITEM attributes[], 128280304Sjkim OPENSSL_ITEM parameters[]); 129280304Sjkimstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, STORE_OBJECT *data, 130280304Sjkim OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 131160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 132280304Sjkim OPENSSL_ITEM search_attributes[], 133280304Sjkim OPENSSL_ITEM add_attributes[], 134280304Sjkim OPENSSL_ITEM modify_attributes[], 135280304Sjkim OPENSSL_ITEM delete_attributes[], 136280304Sjkim OPENSSL_ITEM parameters[]); 137160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 138280304Sjkim OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 139160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 140280304Sjkim OPENSSL_ITEM attributes[], 141280304Sjkim 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[], 146280304Sjkim OPENSSL_ITEM parameters[]); 147160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 148280304Sjkim OPENSSL_ITEM parameters[]); 149280304Sjkimstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)); 150160814Ssimon 151280304Sjkimstatic STORE_METHOD store_memory = { 152280304Sjkim "OpenSSL memory store interface", 153280304Sjkim mem_init, 154280304Sjkim mem_clean, 155280304Sjkim mem_generate, 156280304Sjkim mem_get, 157280304Sjkim mem_store, 158280304Sjkim mem_modify, 159280304Sjkim NULL, /* revoke */ 160280304Sjkim mem_delete, 161280304Sjkim mem_list_start, 162280304Sjkim mem_list_next, 163280304Sjkim mem_list_end, 164280304Sjkim mem_list_endp, 165280304Sjkim NULL, /* update */ 166280304Sjkim mem_lock, 167280304Sjkim mem_unlock, 168280304Sjkim mem_ctrl 169280304Sjkim}; 170160814Ssimon 171160814Ssimonconst STORE_METHOD *STORE_Memory(void) 172280304Sjkim{ 173280304Sjkim return &store_memory; 174280304Sjkim} 175160814Ssimon 176160814Ssimonstatic int mem_init(STORE *s) 177280304Sjkim{ 178280304Sjkim return 1; 179280304Sjkim} 180160814Ssimon 181160814Ssimonstatic void mem_clean(STORE *s) 182280304Sjkim{ 183280304Sjkim return; 184280304Sjkim} 185160814Ssimon 186160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 187280304Sjkim OPENSSL_ITEM attributes[], 188280304Sjkim OPENSSL_ITEM parameters[]) 189280304Sjkim{ 190280304Sjkim STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); 191280304Sjkim return 0; 192280304Sjkim} 193280304Sjkim 194160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 195280304Sjkim OPENSSL_ITEM attributes[], 196280304Sjkim OPENSSL_ITEM parameters[]) 197280304Sjkim{ 198280304Sjkim void *context = mem_list_start(s, type, attributes, parameters); 199160814Ssimon 200280304Sjkim if (context) { 201280304Sjkim STORE_OBJECT *object = mem_list_next(s, context); 202280304Sjkim 203280304Sjkim if (mem_list_end(s, context)) 204280304Sjkim return object; 205280304Sjkim } 206280304Sjkim return NULL; 207280304Sjkim} 208280304Sjkim 209160814Ssimonstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, 210280304Sjkim STORE_OBJECT *data, OPENSSL_ITEM attributes[], 211280304Sjkim OPENSSL_ITEM parameters[]) 212280304Sjkim{ 213280304Sjkim STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); 214280304Sjkim return 0; 215280304Sjkim} 216280304Sjkim 217160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 218280304Sjkim OPENSSL_ITEM search_attributes[], 219280304Sjkim OPENSSL_ITEM add_attributes[], 220280304Sjkim OPENSSL_ITEM modify_attributes[], 221280304Sjkim OPENSSL_ITEM delete_attributes[], 222280304Sjkim OPENSSL_ITEM parameters[]) 223280304Sjkim{ 224280304Sjkim STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); 225280304Sjkim return 0; 226280304Sjkim} 227280304Sjkim 228160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 229280304Sjkim OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) 230280304Sjkim{ 231280304Sjkim STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); 232280304Sjkim return 0; 233280304Sjkim} 234160814Ssimon 235280304Sjkim/* 236280304Sjkim * The list functions may be the hardest to understand. Basically, 237280304Sjkim * mem_list_start compiles a stack of attribute info elements, and puts that 238280304Sjkim * stack into the context to be returned. mem_list_next will then find the 239280304Sjkim * first matching element in the store, and then walk all the way to the end 240280304Sjkim * of the store (since any combination of attribute bits above the starting 241280304Sjkim * point may match the searched for bit pattern...). 242280304Sjkim */ 243160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 244280304Sjkim OPENSSL_ITEM attributes[], 245280304Sjkim OPENSSL_ITEM parameters[]) 246280304Sjkim{ 247280304Sjkim struct mem_ctx_st *context = 248280304Sjkim (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); 249280304Sjkim void *attribute_context = NULL; 250280304Sjkim STORE_ATTR_INFO *attrs = NULL; 251160814Ssimon 252280304Sjkim if (!context) { 253280304Sjkim STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 254280304Sjkim return 0; 255280304Sjkim } 256280304Sjkim memset(context, 0, sizeof(struct mem_ctx_st)); 257160814Ssimon 258280304Sjkim attribute_context = STORE_parse_attrs_start(attributes); 259280304Sjkim if (!attribute_context) { 260280304Sjkim STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); 261280304Sjkim goto err; 262280304Sjkim } 263160814Ssimon 264280304Sjkim while ((attrs = STORE_parse_attrs_next(attribute_context))) { 265280304Sjkim if (context->search_attributes == NULL) { 266280304Sjkim context->search_attributes = 267280304Sjkim sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare); 268280304Sjkim if (!context->search_attributes) { 269280304Sjkim STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 270280304Sjkim goto err; 271280304Sjkim } 272280304Sjkim } 273280304Sjkim sk_STORE_ATTR_INFO_push(context->search_attributes, attrs); 274280304Sjkim } 275280304Sjkim if (!STORE_parse_attrs_endp(attribute_context)) 276280304Sjkim goto err; 277280304Sjkim STORE_parse_attrs_end(attribute_context); 278280304Sjkim context->search_index = -1; 279280304Sjkim context->index = -1; 280280304Sjkim return context; 281160814Ssimon err: 282280304Sjkim if (attribute_context) 283280304Sjkim STORE_parse_attrs_end(attribute_context); 284280304Sjkim mem_list_end(s, context); 285280304Sjkim return NULL; 286280304Sjkim} 287280304Sjkim 288160814Ssimonstatic STORE_OBJECT *mem_list_next(STORE *s, void *handle) 289280304Sjkim{ 290280304Sjkim int i; 291280304Sjkim struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 292280304Sjkim struct mem_object_data_st key = { 0, 0, 1 }; 293280304Sjkim struct mem_data_st *store = (struct mem_data_st *)STORE_get_ex_data(s, 1); 294280304Sjkim int srch; 295280304Sjkim int cres = 0; 296160814Ssimon 297280304Sjkim if (!context) { 298280304Sjkim STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); 299280304Sjkim return NULL; 300280304Sjkim } 301280304Sjkim if (!store) { 302280304Sjkim STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); 303280304Sjkim return NULL; 304280304Sjkim } 305160814Ssimon 306280304Sjkim if (context->search_index == -1) { 307280304Sjkim for (i = 0; 308280304Sjkim i < sk_STORE_ATTR_INFO_num(context->search_attributes); i++) { 309280304Sjkim key.attr_info 310280304Sjkim = sk_STORE_ATTR_INFO_value(context->search_attributes, i); 311280304Sjkim srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key); 312160814Ssimon 313280304Sjkim if (srch >= 0) { 314280304Sjkim context->search_index = srch; 315280304Sjkim break; 316280304Sjkim } 317280304Sjkim } 318280304Sjkim } 319280304Sjkim if (context->search_index < 0) 320280304Sjkim return NULL; 321160814Ssimon 322280304Sjkim key.attr_info = 323280304Sjkim sk_STORE_ATTR_INFO_value(context->search_attributes, 324280304Sjkim context->search_index); 325280304Sjkim for (srch = context->search_index; 326280304Sjkim srch < sk_MEM_OBJECT_DATA_num(store->data) 327280304Sjkim && STORE_ATTR_INFO_in_range(key.attr_info, 328280304Sjkim sk_MEM_OBJECT_DATA_value(store->data, 329280304Sjkim srch)->attr_info) 330280304Sjkim && !(cres = 331280304Sjkim STORE_ATTR_INFO_in_ex(key.attr_info, 332280304Sjkim sk_MEM_OBJECT_DATA_value(store->data, 333280304Sjkim srch)->attr_info)); 334280304Sjkim srch++) ; 335280304Sjkim 336280304Sjkim context->search_index = srch; 337280304Sjkim if (cres) 338280304Sjkim return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object; 339280304Sjkim return NULL; 340280304Sjkim} 341280304Sjkim 342160814Ssimonstatic int mem_list_end(STORE *s, void *handle) 343280304Sjkim{ 344280304Sjkim struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 345160814Ssimon 346280304Sjkim if (!context) { 347280304Sjkim STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); 348280304Sjkim return 0; 349280304Sjkim } 350280304Sjkim if (context && context->search_attributes) 351280304Sjkim sk_STORE_ATTR_INFO_free(context->search_attributes); 352280304Sjkim if (context) 353280304Sjkim OPENSSL_free(context); 354280304Sjkim return 1; 355280304Sjkim} 356280304Sjkim 357160814Ssimonstatic int mem_list_endp(STORE *s, void *handle) 358280304Sjkim{ 359280304Sjkim struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 360160814Ssimon 361280304Sjkim if (!context 362280304Sjkim || context->search_index 363280304Sjkim == sk_STORE_ATTR_INFO_num(context->search_attributes)) 364280304Sjkim return 1; 365280304Sjkim return 0; 366280304Sjkim} 367280304Sjkim 368160814Ssimonstatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 369280304Sjkim OPENSSL_ITEM parameters[]) 370280304Sjkim{ 371280304Sjkim return 1; 372280304Sjkim} 373280304Sjkim 374160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 375280304Sjkim OPENSSL_ITEM parameters[]) 376280304Sjkim{ 377280304Sjkim return 1; 378280304Sjkim} 379280304Sjkim 380280304Sjkimstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)) 381280304Sjkim{ 382280304Sjkim return 1; 383280304Sjkim} 384