1160814Ssimon/* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */ 2296341Sdelphij/* 3296341Sdelphij * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4296341Sdelphij * 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 14296341Sdelphij * 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 64296341Sdelphij/* 65296341Sdelphij * The memory store is currently highly experimental. It's meant to become a 66296341Sdelphij * base store used by other stores for internal caching (for full caching 67296341Sdelphij * support, aging needs to be added). 68296341Sdelphij * 69296341Sdelphij * The database use is meant to support as much attribute association as 70296341Sdelphij * possible, while providing for as small search ranges as possible. This is 71296341Sdelphij * currently provided for by sorting the entries by numbers that are composed 72296341Sdelphij * of bits set at the positions indicated by attribute type codes. This 73296341Sdelphij * provides for ranges determined by the highest attribute type code value. 74296341Sdelphij * A better idea might be to sort by values computed from the range of 75296341Sdelphij * attributes associated with the object (basically, the difference between 76296341Sdelphij * the highest and lowest attribute type code) and it's distance from a base 77296341Sdelphij * (basically, the lowest associated attribute type code). 78296341Sdelphij */ 79160814Ssimon 80296341Sdelphijtypedef struct mem_object_data_st { 81296341Sdelphij STORE_OBJECT *object; 82296341Sdelphij STORE_ATTR_INFO *attr_info; 83296341Sdelphij int references; 84296341Sdelphij} MEM_OBJECT_DATA; 85160814Ssimon 86238405SjkimDECLARE_STACK_OF(MEM_OBJECT_DATA) 87296341Sdelphijstruct mem_data_st { 88296341Sdelphij /* 89296341Sdelphij * sorted with 90296341Sdelphij * STORE_ATTR_INFO_compare(). 91296341Sdelphij */ 92296341Sdelphij STACK_OF(MEM_OBJECT_DATA) *data; 93296341Sdelphij /* 94296341Sdelphij * Currently unused, but can 95296341Sdelphij * be used to add attributes 96296341Sdelphij * from parts of the data. 97296341Sdelphij */ 98296341Sdelphij unsigned int compute_components:1; 99296341Sdelphij}; 100160814Ssimon 101238405SjkimDECLARE_STACK_OF(STORE_ATTR_INFO) 102296341Sdelphijstruct mem_ctx_st { 103296341Sdelphij /* The type we're searching for */ 104296341Sdelphij int type; 105296341Sdelphij /* 106296341Sdelphij * Sets of 107296341Sdelphij * attributes to search for. Each 108296341Sdelphij * element is a STORE_ATTR_INFO. 109296341Sdelphij */ 110296341Sdelphij STACK_OF(STORE_ATTR_INFO) *search_attributes; 111296341Sdelphij /* 112296341Sdelphij * which of the search attributes we 113296341Sdelphij * found a match for, -1 when we still 114296341Sdelphij * haven't found any 115296341Sdelphij */ 116296341Sdelphij int search_index; 117296341Sdelphij /* -1 as long as we're searching for the first */ 118296341Sdelphij int index; 119296341Sdelphij}; 120160814Ssimon 121160814Ssimonstatic int mem_init(STORE *s); 122160814Ssimonstatic void mem_clean(STORE *s); 123160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 124296341Sdelphij OPENSSL_ITEM attributes[], 125296341Sdelphij OPENSSL_ITEM parameters[]); 126160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 127296341Sdelphij OPENSSL_ITEM attributes[], 128296341Sdelphij OPENSSL_ITEM parameters[]); 129296341Sdelphijstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, STORE_OBJECT *data, 130296341Sdelphij OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 131160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 132296341Sdelphij OPENSSL_ITEM search_attributes[], 133296341Sdelphij OPENSSL_ITEM add_attributes[], 134296341Sdelphij OPENSSL_ITEM modify_attributes[], 135296341Sdelphij OPENSSL_ITEM delete_attributes[], 136296341Sdelphij OPENSSL_ITEM parameters[]); 137160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 138296341Sdelphij OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 139160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 140296341Sdelphij OPENSSL_ITEM attributes[], 141296341Sdelphij 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[], 146296341Sdelphij OPENSSL_ITEM parameters[]); 147160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 148296341Sdelphij OPENSSL_ITEM parameters[]); 149296341Sdelphijstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)); 150160814Ssimon 151296341Sdelphijstatic STORE_METHOD store_memory = { 152296341Sdelphij "OpenSSL memory store interface", 153296341Sdelphij mem_init, 154296341Sdelphij mem_clean, 155296341Sdelphij mem_generate, 156296341Sdelphij mem_get, 157296341Sdelphij mem_store, 158296341Sdelphij mem_modify, 159296341Sdelphij NULL, /* revoke */ 160296341Sdelphij mem_delete, 161296341Sdelphij mem_list_start, 162296341Sdelphij mem_list_next, 163296341Sdelphij mem_list_end, 164296341Sdelphij mem_list_endp, 165296341Sdelphij NULL, /* update */ 166296341Sdelphij mem_lock, 167296341Sdelphij mem_unlock, 168296341Sdelphij mem_ctrl 169296341Sdelphij}; 170160814Ssimon 171160814Ssimonconst STORE_METHOD *STORE_Memory(void) 172296341Sdelphij{ 173296341Sdelphij return &store_memory; 174296341Sdelphij} 175160814Ssimon 176160814Ssimonstatic int mem_init(STORE *s) 177296341Sdelphij{ 178296341Sdelphij return 1; 179296341Sdelphij} 180160814Ssimon 181160814Ssimonstatic void mem_clean(STORE *s) 182296341Sdelphij{ 183296341Sdelphij return; 184296341Sdelphij} 185160814Ssimon 186160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 187296341Sdelphij OPENSSL_ITEM attributes[], 188296341Sdelphij OPENSSL_ITEM parameters[]) 189296341Sdelphij{ 190296341Sdelphij STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); 191296341Sdelphij return 0; 192296341Sdelphij} 193296341Sdelphij 194160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 195296341Sdelphij OPENSSL_ITEM attributes[], 196296341Sdelphij OPENSSL_ITEM parameters[]) 197296341Sdelphij{ 198296341Sdelphij void *context = mem_list_start(s, type, attributes, parameters); 199160814Ssimon 200296341Sdelphij if (context) { 201296341Sdelphij STORE_OBJECT *object = mem_list_next(s, context); 202296341Sdelphij 203296341Sdelphij if (mem_list_end(s, context)) 204296341Sdelphij return object; 205296341Sdelphij } 206296341Sdelphij return NULL; 207296341Sdelphij} 208296341Sdelphij 209160814Ssimonstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, 210296341Sdelphij STORE_OBJECT *data, OPENSSL_ITEM attributes[], 211296341Sdelphij OPENSSL_ITEM parameters[]) 212296341Sdelphij{ 213296341Sdelphij STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); 214296341Sdelphij return 0; 215296341Sdelphij} 216296341Sdelphij 217160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 218296341Sdelphij OPENSSL_ITEM search_attributes[], 219296341Sdelphij OPENSSL_ITEM add_attributes[], 220296341Sdelphij OPENSSL_ITEM modify_attributes[], 221296341Sdelphij OPENSSL_ITEM delete_attributes[], 222296341Sdelphij OPENSSL_ITEM parameters[]) 223296341Sdelphij{ 224296341Sdelphij STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); 225296341Sdelphij return 0; 226296341Sdelphij} 227296341Sdelphij 228160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 229296341Sdelphij OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) 230296341Sdelphij{ 231296341Sdelphij STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); 232296341Sdelphij return 0; 233296341Sdelphij} 234160814Ssimon 235296341Sdelphij/* 236296341Sdelphij * The list functions may be the hardest to understand. Basically, 237296341Sdelphij * mem_list_start compiles a stack of attribute info elements, and puts that 238296341Sdelphij * stack into the context to be returned. mem_list_next will then find the 239296341Sdelphij * first matching element in the store, and then walk all the way to the end 240296341Sdelphij * of the store (since any combination of attribute bits above the starting 241296341Sdelphij * point may match the searched for bit pattern...). 242296341Sdelphij */ 243160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 244296341Sdelphij OPENSSL_ITEM attributes[], 245296341Sdelphij OPENSSL_ITEM parameters[]) 246296341Sdelphij{ 247296341Sdelphij struct mem_ctx_st *context = 248296341Sdelphij (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); 249296341Sdelphij void *attribute_context = NULL; 250296341Sdelphij STORE_ATTR_INFO *attrs = NULL; 251160814Ssimon 252296341Sdelphij if (!context) { 253296341Sdelphij STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 254296341Sdelphij return 0; 255296341Sdelphij } 256296341Sdelphij memset(context, 0, sizeof(struct mem_ctx_st)); 257160814Ssimon 258296341Sdelphij attribute_context = STORE_parse_attrs_start(attributes); 259296341Sdelphij if (!attribute_context) { 260296341Sdelphij STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); 261296341Sdelphij goto err; 262296341Sdelphij } 263160814Ssimon 264296341Sdelphij while ((attrs = STORE_parse_attrs_next(attribute_context))) { 265296341Sdelphij if (context->search_attributes == NULL) { 266296341Sdelphij context->search_attributes = 267296341Sdelphij sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare); 268296341Sdelphij if (!context->search_attributes) { 269296341Sdelphij STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 270296341Sdelphij goto err; 271296341Sdelphij } 272296341Sdelphij } 273296341Sdelphij sk_STORE_ATTR_INFO_push(context->search_attributes, attrs); 274296341Sdelphij } 275296341Sdelphij if (!STORE_parse_attrs_endp(attribute_context)) 276296341Sdelphij goto err; 277296341Sdelphij STORE_parse_attrs_end(attribute_context); 278296341Sdelphij context->search_index = -1; 279296341Sdelphij context->index = -1; 280296341Sdelphij return context; 281160814Ssimon err: 282296341Sdelphij if (attribute_context) 283296341Sdelphij STORE_parse_attrs_end(attribute_context); 284296341Sdelphij mem_list_end(s, context); 285296341Sdelphij return NULL; 286296341Sdelphij} 287296341Sdelphij 288160814Ssimonstatic STORE_OBJECT *mem_list_next(STORE *s, void *handle) 289296341Sdelphij{ 290296341Sdelphij int i; 291296341Sdelphij struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 292296341Sdelphij struct mem_object_data_st key = { 0, 0, 1 }; 293296341Sdelphij struct mem_data_st *store = (struct mem_data_st *)STORE_get_ex_data(s, 1); 294296341Sdelphij int srch; 295296341Sdelphij int cres = 0; 296160814Ssimon 297296341Sdelphij if (!context) { 298296341Sdelphij STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); 299296341Sdelphij return NULL; 300296341Sdelphij } 301296341Sdelphij if (!store) { 302296341Sdelphij STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); 303296341Sdelphij return NULL; 304296341Sdelphij } 305160814Ssimon 306296341Sdelphij if (context->search_index == -1) { 307296341Sdelphij for (i = 0; 308296341Sdelphij i < sk_STORE_ATTR_INFO_num(context->search_attributes); i++) { 309296341Sdelphij key.attr_info 310296341Sdelphij = sk_STORE_ATTR_INFO_value(context->search_attributes, i); 311296341Sdelphij srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key); 312160814Ssimon 313296341Sdelphij if (srch >= 0) { 314296341Sdelphij context->search_index = srch; 315296341Sdelphij break; 316296341Sdelphij } 317296341Sdelphij } 318296341Sdelphij } 319296341Sdelphij if (context->search_index < 0) 320296341Sdelphij return NULL; 321160814Ssimon 322296341Sdelphij key.attr_info = 323296341Sdelphij sk_STORE_ATTR_INFO_value(context->search_attributes, 324296341Sdelphij context->search_index); 325296341Sdelphij for (srch = context->search_index; 326296341Sdelphij srch < sk_MEM_OBJECT_DATA_num(store->data) 327296341Sdelphij && STORE_ATTR_INFO_in_range(key.attr_info, 328296341Sdelphij sk_MEM_OBJECT_DATA_value(store->data, 329296341Sdelphij srch)->attr_info) 330296341Sdelphij && !(cres = 331296341Sdelphij STORE_ATTR_INFO_in_ex(key.attr_info, 332296341Sdelphij sk_MEM_OBJECT_DATA_value(store->data, 333296341Sdelphij srch)->attr_info)); 334296341Sdelphij srch++) ; 335296341Sdelphij 336296341Sdelphij context->search_index = srch; 337296341Sdelphij if (cres) 338296341Sdelphij return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object; 339296341Sdelphij return NULL; 340296341Sdelphij} 341296341Sdelphij 342160814Ssimonstatic int mem_list_end(STORE *s, void *handle) 343296341Sdelphij{ 344296341Sdelphij struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 345160814Ssimon 346296341Sdelphij if (!context) { 347296341Sdelphij STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); 348296341Sdelphij return 0; 349296341Sdelphij } 350296341Sdelphij if (context && context->search_attributes) 351296341Sdelphij sk_STORE_ATTR_INFO_free(context->search_attributes); 352296341Sdelphij if (context) 353296341Sdelphij OPENSSL_free(context); 354296341Sdelphij return 1; 355296341Sdelphij} 356296341Sdelphij 357160814Ssimonstatic int mem_list_endp(STORE *s, void *handle) 358296341Sdelphij{ 359296341Sdelphij struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 360160814Ssimon 361296341Sdelphij if (!context 362296341Sdelphij || context->search_index 363296341Sdelphij == sk_STORE_ATTR_INFO_num(context->search_attributes)) 364296341Sdelphij return 1; 365296341Sdelphij return 0; 366296341Sdelphij} 367296341Sdelphij 368160814Ssimonstatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 369296341Sdelphij OPENSSL_ITEM parameters[]) 370296341Sdelphij{ 371296341Sdelphij return 1; 372296341Sdelphij} 373296341Sdelphij 374160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 375296341Sdelphij OPENSSL_ITEM parameters[]) 376296341Sdelphij{ 377296341Sdelphij return 1; 378296341Sdelphij} 379296341Sdelphij 380296341Sdelphijstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)) 381296341Sdelphij{ 382296341Sdelphij return 1; 383296341Sdelphij} 384