1160814Ssimon/* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */ 2296465Sdelphij/* 3296465Sdelphij * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 4296465Sdelphij * 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 14296465Sdelphij * 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 64296465Sdelphij/* 65296465Sdelphij * The memory store is currently highly experimental. It's meant to become a 66296465Sdelphij * base store used by other stores for internal caching (for full caching 67296465Sdelphij * support, aging needs to be added). 68296465Sdelphij * 69296465Sdelphij * The database use is meant to support as much attribute association as 70296465Sdelphij * possible, while providing for as small search ranges as possible. This is 71296465Sdelphij * currently provided for by sorting the entries by numbers that are composed 72296465Sdelphij * of bits set at the positions indicated by attribute type codes. This 73296465Sdelphij * provides for ranges determined by the highest attribute type code value. 74296465Sdelphij * A better idea might be to sort by values computed from the range of 75296465Sdelphij * attributes associated with the object (basically, the difference between 76296465Sdelphij * the highest and lowest attribute type code) and it's distance from a base 77296465Sdelphij * (basically, the lowest associated attribute type code). 78296465Sdelphij */ 79160814Ssimon 80296465Sdelphijstruct mem_object_data_st { 81296465Sdelphij STORE_OBJECT *object; 82296465Sdelphij STORE_ATTR_INFO *attr_info; 83296465Sdelphij int references; 84296465Sdelphij}; 85160814Ssimon 86296465Sdelphijstruct mem_data_st { 87296465Sdelphij /* 88296465Sdelphij * A stack of mem_object_data_st, 89296465Sdelphij * sorted with STORE_ATTR_INFO_compare(). 90296465Sdelphij */ 91296465Sdelphij STACK *data; 92296465Sdelphij /* 93296465Sdelphij * Currently unused, but can be used to add attributes from parts of the 94296465Sdelphij * data. 95296465Sdelphij */ 96296465Sdelphij unsigned int compute_components:1; 97296465Sdelphij}; 98160814Ssimon 99296465Sdelphijstruct mem_ctx_st { 100296465Sdelphij /* The type we're searching for */ 101296465Sdelphij int type; 102296465Sdelphij /* 103296465Sdelphij * Sets of attributes to search for. 104296465Sdelphij * Each element is a STORE_ATTR_INFO. 105296465Sdelphij */ 106296465Sdelphij STACK *search_attributes; 107296465Sdelphij /* 108296465Sdelphij * which of the search attributes we found a match 109296465Sdelphij * for, -1 when we still haven't found any 110296465Sdelphij */ 111296465Sdelphij int search_index; 112296465Sdelphij /* -1 as long as we're searching for the first */ 113296465Sdelphij int index; 114296465Sdelphij}; 115160814Ssimon 116160814Ssimonstatic int mem_init(STORE *s); 117160814Ssimonstatic void mem_clean(STORE *s); 118160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 119296465Sdelphij OPENSSL_ITEM attributes[], 120296465Sdelphij OPENSSL_ITEM parameters[]); 121160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 122296465Sdelphij OPENSSL_ITEM attributes[], 123296465Sdelphij OPENSSL_ITEM parameters[]); 124296465Sdelphijstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, STORE_OBJECT *data, 125296465Sdelphij OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 126160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 127296465Sdelphij OPENSSL_ITEM search_attributes[], 128296465Sdelphij OPENSSL_ITEM add_attributes[], 129296465Sdelphij OPENSSL_ITEM modify_attributes[], 130296465Sdelphij OPENSSL_ITEM delete_attributes[], 131296465Sdelphij OPENSSL_ITEM parameters[]); 132160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 133296465Sdelphij OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 134160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 135296465Sdelphij OPENSSL_ITEM attributes[], 136296465Sdelphij OPENSSL_ITEM parameters[]); 137160814Ssimonstatic STORE_OBJECT *mem_list_next(STORE *s, void *handle); 138160814Ssimonstatic int mem_list_end(STORE *s, void *handle); 139160814Ssimonstatic int mem_list_endp(STORE *s, void *handle); 140160814Ssimonstatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 141296465Sdelphij OPENSSL_ITEM parameters[]); 142160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 143296465Sdelphij OPENSSL_ITEM parameters[]); 144296465Sdelphijstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)); 145160814Ssimon 146296465Sdelphijstatic STORE_METHOD store_memory = { 147296465Sdelphij "OpenSSL memory store interface", 148296465Sdelphij mem_init, 149296465Sdelphij mem_clean, 150296465Sdelphij mem_generate, 151296465Sdelphij mem_get, 152296465Sdelphij mem_store, 153296465Sdelphij mem_modify, 154296465Sdelphij NULL, /* revoke */ 155296465Sdelphij mem_delete, 156296465Sdelphij mem_list_start, 157296465Sdelphij mem_list_next, 158296465Sdelphij mem_list_end, 159296465Sdelphij mem_list_endp, 160296465Sdelphij NULL, /* update */ 161296465Sdelphij mem_lock, 162296465Sdelphij mem_unlock, 163296465Sdelphij mem_ctrl 164296465Sdelphij}; 165160814Ssimon 166160814Ssimonconst STORE_METHOD *STORE_Memory(void) 167296465Sdelphij{ 168296465Sdelphij return &store_memory; 169296465Sdelphij} 170160814Ssimon 171160814Ssimonstatic int mem_init(STORE *s) 172296465Sdelphij{ 173296465Sdelphij return 1; 174296465Sdelphij} 175160814Ssimon 176160814Ssimonstatic void mem_clean(STORE *s) 177296465Sdelphij{ 178296465Sdelphij return; 179296465Sdelphij} 180160814Ssimon 181160814Ssimonstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 182296465Sdelphij OPENSSL_ITEM attributes[], 183296465Sdelphij OPENSSL_ITEM parameters[]) 184296465Sdelphij{ 185296465Sdelphij STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); 186296465Sdelphij return 0; 187296465Sdelphij} 188296465Sdelphij 189160814Ssimonstatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 190296465Sdelphij OPENSSL_ITEM attributes[], 191296465Sdelphij OPENSSL_ITEM parameters[]) 192296465Sdelphij{ 193296465Sdelphij void *context = mem_list_start(s, type, attributes, parameters); 194160814Ssimon 195296465Sdelphij if (context) { 196296465Sdelphij STORE_OBJECT *object = mem_list_next(s, context); 197296465Sdelphij 198296465Sdelphij if (mem_list_end(s, context)) 199296465Sdelphij return object; 200296465Sdelphij } 201296465Sdelphij return NULL; 202296465Sdelphij} 203296465Sdelphij 204160814Ssimonstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, 205296465Sdelphij STORE_OBJECT *data, OPENSSL_ITEM attributes[], 206296465Sdelphij OPENSSL_ITEM parameters[]) 207296465Sdelphij{ 208296465Sdelphij STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); 209296465Sdelphij return 0; 210296465Sdelphij} 211296465Sdelphij 212160814Ssimonstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 213296465Sdelphij OPENSSL_ITEM search_attributes[], 214296465Sdelphij OPENSSL_ITEM add_attributes[], 215296465Sdelphij OPENSSL_ITEM modify_attributes[], 216296465Sdelphij OPENSSL_ITEM delete_attributes[], 217296465Sdelphij OPENSSL_ITEM parameters[]) 218296465Sdelphij{ 219296465Sdelphij STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); 220296465Sdelphij return 0; 221296465Sdelphij} 222296465Sdelphij 223160814Ssimonstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 224296465Sdelphij OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) 225296465Sdelphij{ 226296465Sdelphij STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); 227296465Sdelphij return 0; 228296465Sdelphij} 229160814Ssimon 230296465Sdelphij/* 231296465Sdelphij * The list functions may be the hardest to understand. Basically, 232296465Sdelphij * mem_list_start compiles a stack of attribute info elements, and puts that 233296465Sdelphij * stack into the context to be returned. mem_list_next will then find the 234296465Sdelphij * first matching element in the store, and then walk all the way to the end 235296465Sdelphij * of the store (since any combination of attribute bits above the starting 236296465Sdelphij * point may match the searched for bit pattern...). 237296465Sdelphij */ 238160814Ssimonstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 239296465Sdelphij OPENSSL_ITEM attributes[], 240296465Sdelphij OPENSSL_ITEM parameters[]) 241296465Sdelphij{ 242296465Sdelphij struct mem_ctx_st *context = 243296465Sdelphij (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); 244296465Sdelphij void *attribute_context = NULL; 245296465Sdelphij STORE_ATTR_INFO *attrs = NULL; 246160814Ssimon 247296465Sdelphij if (!context) { 248296465Sdelphij STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 249296465Sdelphij return 0; 250296465Sdelphij } 251296465Sdelphij memset(context, 0, sizeof(struct mem_ctx_st)); 252160814Ssimon 253296465Sdelphij attribute_context = STORE_parse_attrs_start(attributes); 254296465Sdelphij if (!attribute_context) { 255296465Sdelphij STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); 256296465Sdelphij goto err; 257296465Sdelphij } 258160814Ssimon 259296465Sdelphij while ((attrs = STORE_parse_attrs_next(attribute_context))) { 260296465Sdelphij if (context->search_attributes == NULL) { 261296465Sdelphij context->search_attributes = 262296465Sdelphij sk_new((int (*)(const char *const *, const char *const *)) 263296465Sdelphij STORE_ATTR_INFO_compare); 264296465Sdelphij if (!context->search_attributes) { 265296465Sdelphij STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 266296465Sdelphij goto err; 267296465Sdelphij } 268296465Sdelphij } 269296465Sdelphij sk_push(context->search_attributes, (char *)attrs); 270296465Sdelphij } 271296465Sdelphij if (!STORE_parse_attrs_endp(attribute_context)) 272296465Sdelphij goto err; 273296465Sdelphij STORE_parse_attrs_end(attribute_context); 274296465Sdelphij context->search_index = -1; 275296465Sdelphij context->index = -1; 276296465Sdelphij return context; 277160814Ssimon err: 278296465Sdelphij if (attribute_context) 279296465Sdelphij STORE_parse_attrs_end(attribute_context); 280296465Sdelphij mem_list_end(s, context); 281296465Sdelphij return NULL; 282296465Sdelphij} 283296465Sdelphij 284160814Ssimonstatic STORE_OBJECT *mem_list_next(STORE *s, void *handle) 285296465Sdelphij{ 286296465Sdelphij int i; 287296465Sdelphij struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 288296465Sdelphij struct mem_object_data_st key = { 0, 0, 1 }; 289296465Sdelphij struct mem_data_st *store = (struct mem_data_st *)STORE_get_ex_data(s, 1); 290296465Sdelphij int srch; 291296465Sdelphij int cres = 0; 292160814Ssimon 293296465Sdelphij if (!context) { 294296465Sdelphij STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); 295296465Sdelphij return NULL; 296296465Sdelphij } 297296465Sdelphij if (!store) { 298296465Sdelphij STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); 299296465Sdelphij return NULL; 300296465Sdelphij } 301160814Ssimon 302296465Sdelphij if (context->search_index == -1) { 303296465Sdelphij for (i = 0; i < sk_num(context->search_attributes); i++) { 304296465Sdelphij key.attr_info = 305296465Sdelphij (STORE_ATTR_INFO *)sk_value(context->search_attributes, i); 306296465Sdelphij srch = sk_find_ex(store->data, (char *)&key); 307160814Ssimon 308296465Sdelphij if (srch >= 0) { 309296465Sdelphij context->search_index = srch; 310296465Sdelphij break; 311296465Sdelphij } 312296465Sdelphij } 313296465Sdelphij } 314296465Sdelphij if (context->search_index < 0) 315296465Sdelphij return NULL; 316160814Ssimon 317296465Sdelphij key.attr_info = 318296465Sdelphij (STORE_ATTR_INFO *)sk_value(context->search_attributes, 319296465Sdelphij context->search_index); 320296465Sdelphij for (srch = context->search_index; srch < sk_num(store->data) 321296465Sdelphij && STORE_ATTR_INFO_in_range(key.attr_info, 322296465Sdelphij (STORE_ATTR_INFO *)sk_value(store->data, 323296465Sdelphij srch)) 324296465Sdelphij && !(cres = 325296465Sdelphij STORE_ATTR_INFO_in_ex(key.attr_info, 326296465Sdelphij (STORE_ATTR_INFO *)sk_value(store->data, 327296465Sdelphij srch))); 328296465Sdelphij srch++) ; 329296465Sdelphij 330296465Sdelphij context->search_index = srch; 331296465Sdelphij if (cres) 332296465Sdelphij return ((struct mem_object_data_st *)sk_value(store->data, 333296465Sdelphij srch))->object; 334296465Sdelphij return NULL; 335296465Sdelphij} 336296465Sdelphij 337160814Ssimonstatic int mem_list_end(STORE *s, void *handle) 338296465Sdelphij{ 339296465Sdelphij struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 340160814Ssimon 341296465Sdelphij if (!context) { 342296465Sdelphij STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); 343296465Sdelphij return 0; 344296465Sdelphij } 345296465Sdelphij if (context && context->search_attributes) 346296465Sdelphij sk_free(context->search_attributes); 347296465Sdelphij if (context) 348296465Sdelphij OPENSSL_free(context); 349296465Sdelphij return 1; 350296465Sdelphij} 351296465Sdelphij 352160814Ssimonstatic int mem_list_endp(STORE *s, void *handle) 353296465Sdelphij{ 354296465Sdelphij struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 355160814Ssimon 356296465Sdelphij if (!context 357296465Sdelphij || context->search_index == sk_num(context->search_attributes)) 358296465Sdelphij return 1; 359296465Sdelphij return 0; 360296465Sdelphij} 361296465Sdelphij 362160814Ssimonstatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 363296465Sdelphij OPENSSL_ITEM parameters[]) 364296465Sdelphij{ 365296465Sdelphij return 1; 366296465Sdelphij} 367296465Sdelphij 368160814Ssimonstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 369296465Sdelphij OPENSSL_ITEM parameters[]) 370296465Sdelphij{ 371296465Sdelphij return 1; 372296465Sdelphij} 373296465Sdelphij 374296465Sdelphijstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)) 375296465Sdelphij{ 376296465Sdelphij return 1; 377296465Sdelphij} 378