str_mem.c revision 296341
1139823Simp/* crypto/store/str_mem.c -*- mode:C; c-file-style: "eay" -*- */ 221259Swollman/* 321259Swollman * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project 421259Swollman * 2003. 521259Swollman */ 621259Swollman/* ==================================================================== 721259Swollman * Copyright (c) 2003 The OpenSSL Project. All rights reserved. 821259Swollman * 921259Swollman * Redistribution and use in source and binary forms, with or without 1021259Swollman * modification, are permitted provided that the following conditions 1121259Swollman * are met: 1221259Swollman * 1321259Swollman * 1. Redistributions of source code must retain the above copyright 1421259Swollman * notice, this list of conditions and the following disclaimer. 1521259Swollman * 1621259Swollman * 2. Redistributions in binary form must reproduce the above copyright 1721259Swollman * notice, this list of conditions and the following disclaimer in 1821259Swollman * the documentation and/or other materials provided with the 1921259Swollman * distribution. 2021259Swollman * 2121259Swollman * 3. All advertising materials mentioning features or use of this 2221259Swollman * software must display the following acknowledgment: 2321259Swollman * "This product includes software developed by the OpenSSL Project 2421259Swollman * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 2521259Swollman * 2621259Swollman * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 2721259Swollman * endorse or promote products derived from this software without 2821259Swollman * prior written permission. For written permission, please contact 2921259Swollman * openssl-core@openssl.org. 3050477Speter * 3121259Swollman * 5. Products derived from this software may not be called "OpenSSL" 3221259Swollman * nor may "OpenSSL" appear in their names without prior written 3321259Swollman * permission of the OpenSSL Project. 3421259Swollman * 3521259Swollman * 6. Redistributions of any form whatsoever must retain the following 3621259Swollman * acknowledgment: 3721259Swollman * "This product includes software developed by the OpenSSL Project 3821259Swollman * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 3921259Swollman * 4021259Swollman * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 4121259Swollman * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4221259Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 4321259Swollman * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4421259Swollman * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 4521259Swollman * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 4621259Swollman * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 4721259Swollman * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4821259Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 4921259Swollman * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5021259Swollman * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51108533Sschweikh * OF THE POSSIBILITY OF SUCH DAMAGE. 5221259Swollman * ==================================================================== 5321259Swollman * 5421259Swollman * This product includes cryptographic software written by Eric Young 5521259Swollman * (eay@cryptsoft.com). This product includes software written by Tim 56108533Sschweikh * Hudson (tjh@cryptsoft.com). 5721259Swollman * 5821259Swollman */ 5921259Swollman 6021259Swollman#include <string.h> 6121259Swollman#include <openssl/err.h> 6221259Swollman#include "str_locl.h" 6321259Swollman 6421259Swollman/* 6521259Swollman * The memory store is currently highly experimental. It's meant to become a 6683366Sjulian * base store used by other stores for internal caching (for full caching 6721259Swollman * support, aging needs to be added). 6885074Sru * 6921259Swollman * The database use is meant to support as much attribute association as 7021259Swollman * possible, while providing for as small search ranges as possible. This is 71142215Sglebius * currently provided for by sorting the entries by numbers that are composed 72155051Sglebius * of bits set at the positions indicated by attribute type codes. This 7321259Swollman * provides for ranges determined by the highest attribute type code value. 7421259Swollman * A better idea might be to sort by values computed from the range of 7521259Swollman * attributes associated with the object (basically, the difference between 7621259Swollman * the highest and lowest attribute type code) and it's distance from a base 7769224Sjlemon * (basically, the lowest associated attribute type code). 7869152Sjlemon */ 79126264Smlaier 80186207Skmacytypedef struct mem_object_data_st { 8169224Sjlemon STORE_OBJECT *object; 8274914Sjhb STORE_ATTR_INFO *attr_info; 8374914Sjhb int references; 84186199Skmacy} MEM_OBJECT_DATA; 8583130Sjlemon 86132712SrwatsonDECLARE_STACK_OF(MEM_OBJECT_DATA) 8769152Sjlemonstruct mem_data_st { 88121816Sbrooks /* 89121816Sbrooks * sorted with 90130416Smlaier * STORE_ATTR_INFO_compare(). 91130416Smlaier */ 9260938Sjake STACK_OF(MEM_OBJECT_DATA) *data; 9360938Sjake /* 9460938Sjake * Currently unused, but can 9572084Sphk * be used to add attributes 96159781Smlaier * from parts of the data. 9721259Swollman */ 9821259Swollman unsigned int compute_components:1; 9921259Swollman}; 10021259Swollman 10121259SwollmanDECLARE_STACK_OF(STORE_ATTR_INFO) 10221259Swollmanstruct mem_ctx_st { 10321259Swollman /* The type we're searching for */ 10421259Swollman int type; 10521259Swollman /* 10621259Swollman * Sets of 10769152Sjlemon * attributes to search for. Each 10821259Swollman * element is a STORE_ATTR_INFO. 10921259Swollman */ 11021259Swollman STACK_OF(STORE_ATTR_INFO) *search_attributes; 11121259Swollman /* 11221259Swollman * which of the search attributes we 11321259Swollman * found a match for, -1 when we still 11421259Swollman * haven't found any 11584380Smjacob */ 11621259Swollman int search_index; 11721259Swollman /* -1 as long as we're searching for the first */ 118147256Sbrooks int index; 11960938Sjake}; 120121816Sbrooks 121121816Sbrooksstatic int mem_init(STORE *s); 122121816Sbrooksstatic void mem_clean(STORE *s); 12321259Swollmanstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 124128291Sluigi OPENSSL_ITEM attributes[], 125128291Sluigi OPENSSL_ITEM parameters[]); 126128315Sluigistatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 127128315Sluigi OPENSSL_ITEM attributes[], 128128315Sluigi OPENSSL_ITEM parameters[]); 129128315Sluigistatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, STORE_OBJECT *data, 130128291Sluigi OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 131128315Sluigistatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 132152315Sru OPENSSL_ITEM search_attributes[], 133128291Sluigi OPENSSL_ITEM add_attributes[], 134133741Sjmg OPENSSL_ITEM modify_attributes[], 13583130Sjlemon OPENSSL_ITEM delete_attributes[], 136142901Sglebius OPENSSL_ITEM parameters[]); 13721259Swollmanstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 13821259Swollman OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); 13921259Swollmanstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 140155051Sglebius OPENSSL_ITEM attributes[], 141102052Ssobomax OPENSSL_ITEM parameters[]); 142162070Sandrestatic STORE_OBJECT *mem_list_next(STORE *s, void *handle); 143162070Sandrestatic int mem_list_end(STORE *s, void *handle); 14421259Swollmanstatic int mem_list_endp(STORE *s, void *handle); 14521259Swollmanstatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 14621259Swollman OPENSSL_ITEM parameters[]); 14721404Swollmanstatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 14821404Swollman OPENSSL_ITEM parameters[]); 14921259Swollmanstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)); 15021259Swollman 15192725Salfredstatic STORE_METHOD store_memory = { 15292725Salfred "OpenSSL memory store interface", 153106931Ssam mem_init, 154106931Ssam mem_clean, 15521259Swollman mem_generate, 15692725Salfred mem_get, 15721259Swollman mem_store, 15892725Salfred mem_modify, 15921259Swollman NULL, /* revoke */ 16092725Salfred mem_delete, 16121259Swollman mem_list_start, 16292725Salfred mem_list_next, 16321404Swollman mem_list_end, 16492725Salfred mem_list_endp, 165152315Sru NULL, /* update */ 166174388Skmacy mem_lock, 167148265Srwatson mem_unlock, 168137062Srwatson mem_ctrl 169130416Smlaier}; 170123220Simp 171127828Sluigiconst STORE_METHOD *STORE_Memory(void) 172146986Sthompsa{ 173146986Sthompsa return &store_memory; 174122524Srwatson} 175121161Sume 176127828Sluigistatic int mem_init(STORE *s) 177127828Sluigi{ 178121161Sume return 1; 179121470Sume} 180186199Skmacy 181132712Srwatsonstatic void mem_clean(STORE *s) 182145320Sglebius{ 183148640Srwatson return; 184186119Sqingli} 185152209Sthompsa 186159781Smlaierstatic STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, 187159781Smlaier OPENSSL_ITEM attributes[], 188159781Smlaier OPENSSL_ITEM parameters[]) 189168793Sthompsa{ 190186199Skmacy STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); 191186199Skmacy return 0; 192185162Skmacy} 193185162Skmacy 194185162Skmacystatic STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, 195174388Skmacy OPENSSL_ITEM attributes[], 19621259Swollman OPENSSL_ITEM parameters[]) 19769152Sjlemon{ 19892725Salfred void *context = mem_list_start(s, type, attributes, parameters); 19921259Swollman 200128376Sluigi if (context) { 201128376Sluigi STORE_OBJECT *object = mem_list_next(s, context); 202128376Sluigi 203128376Sluigi if (mem_list_end(s, context)) 20421259Swollman return object; 20521259Swollman } 20621259Swollman return NULL; 20721259Swollman} 20821259Swollman 20921259Swollmanstatic int mem_store(STORE *s, STORE_OBJECT_TYPES type, 210128871Sandre STORE_OBJECT *data, OPENSSL_ITEM attributes[], 21121259Swollman OPENSSL_ITEM parameters[]) 21258698Sjlemon{ 21321259Swollman STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); 21421259Swollman return 0; 21521259Swollman} 21621259Swollman 21721259Swollmanstatic int mem_modify(STORE *s, STORE_OBJECT_TYPES type, 21821259Swollman OPENSSL_ITEM search_attributes[], 21921259Swollman OPENSSL_ITEM add_attributes[], 22021259Swollman OPENSSL_ITEM modify_attributes[], 22121259Swollman OPENSSL_ITEM delete_attributes[], 22221259Swollman OPENSSL_ITEM parameters[]) 22321259Swollman{ 22421259Swollman STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); 225136950Sjmg return 0; 22621259Swollman} 22753541Sshin 22853541Sshinstatic int mem_delete(STORE *s, STORE_OBJECT_TYPES type, 22953541Sshin OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) 230160981Sbrooks{ 23153541Sshin STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); 23221259Swollman return 0; 233148640Srwatson} 234148640Srwatson 235148640Srwatson/* 236148640Srwatson * The list functions may be the hardest to understand. Basically, 237148640Srwatson * mem_list_start compiles a stack of attribute info elements, and puts that 238148640Srwatson * stack into the context to be returned. mem_list_next will then find the 239148640Srwatson * first matching element in the store, and then walk all the way to the end 240148640Srwatson * of the store (since any combination of attribute bits above the starting 241148640Srwatson * point may match the searched for bit pattern...). 242148640Srwatson */ 24321259Swollmanstatic void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, 24421259Swollman OPENSSL_ITEM attributes[], 24521259Swollman OPENSSL_ITEM parameters[]) 24621259Swollman{ 24721259Swollman struct mem_ctx_st *context = 24872200Sbmilekic (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); 24972200Sbmilekic void *attribute_context = NULL; 250130416Smlaier STORE_ATTR_INFO *attrs = NULL; 25169152Sjlemon 25269152Sjlemon if (!context) { 25369152Sjlemon STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 25421259Swollman return 0; 25569152Sjlemon } 25669152Sjlemon memset(context, 0, sizeof(struct mem_ctx_st)); 25769152Sjlemon 25869152Sjlemon attribute_context = STORE_parse_attrs_start(attributes); 25969152Sjlemon if (!attribute_context) { 26069152Sjlemon STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); 26169152Sjlemon goto err; 26269152Sjlemon } 26369152Sjlemon 26469152Sjlemon while ((attrs = STORE_parse_attrs_next(attribute_context))) { 26569152Sjlemon if (context->search_attributes == NULL) { 26669152Sjlemon context->search_attributes = 26769152Sjlemon sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare); 26869152Sjlemon if (!context->search_attributes) { 26969152Sjlemon STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); 27069152Sjlemon goto err; 27169152Sjlemon } 27269152Sjlemon } 27369152Sjlemon sk_STORE_ATTR_INFO_push(context->search_attributes, attrs); 27469152Sjlemon } 27569152Sjlemon if (!STORE_parse_attrs_endp(attribute_context)) 27669152Sjlemon goto err; 27769152Sjlemon STORE_parse_attrs_end(attribute_context); 27869152Sjlemon context->search_index = -1; 27969152Sjlemon context->index = -1; 28069152Sjlemon return context; 28169152Sjlemon err: 28269152Sjlemon if (attribute_context) 28369152Sjlemon STORE_parse_attrs_end(attribute_context); 28469152Sjlemon mem_list_end(s, context); 28569152Sjlemon return NULL; 28669152Sjlemon} 28769152Sjlemon 288136950Sjmgstatic STORE_OBJECT *mem_list_next(STORE *s, void *handle) 28969152Sjlemon{ 29069152Sjlemon int i; 29169152Sjlemon struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 29269152Sjlemon struct mem_object_data_st key = { 0, 0, 1 }; 29369152Sjlemon struct mem_data_st *store = (struct mem_data_st *)STORE_get_ex_data(s, 1); 29469152Sjlemon int srch; 29569152Sjlemon int cres = 0; 29669152Sjlemon 29769152Sjlemon if (!context) { 29869152Sjlemon STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); 29969152Sjlemon return NULL; 30069152Sjlemon } 301130416Smlaier if (!store) { 302130416Smlaier STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); 303130416Smlaier return NULL; 304130416Smlaier } 30569152Sjlemon 30669152Sjlemon if (context->search_index == -1) { 30769152Sjlemon for (i = 0; 30869152Sjlemon i < sk_STORE_ATTR_INFO_num(context->search_attributes); i++) { 30969152Sjlemon key.attr_info 31069152Sjlemon = sk_STORE_ATTR_INFO_value(context->search_attributes, i); 31169152Sjlemon srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key); 31269152Sjlemon 31369152Sjlemon if (srch >= 0) { 314130416Smlaier context->search_index = srch; 315130416Smlaier break; 316130416Smlaier } 317130416Smlaier } 318130416Smlaier } 319130416Smlaier if (context->search_index < 0) 32055205Speter return NULL; 321126264Smlaier 322126264Smlaier key.attr_info = 323126264Smlaier sk_STORE_ATTR_INFO_value(context->search_attributes, 324126264Smlaier context->search_index); 325126264Smlaier for (srch = context->search_index; 326126264Smlaier srch < sk_MEM_OBJECT_DATA_num(store->data) 327126264Smlaier && STORE_ATTR_INFO_in_range(key.attr_info, 328126264Smlaier sk_MEM_OBJECT_DATA_value(store->data, 329126264Smlaier srch)->attr_info) 330126264Smlaier && !(cres = 331159781Smlaier STORE_ATTR_INFO_in_ex(key.attr_info, 332159781Smlaier sk_MEM_OBJECT_DATA_value(store->data, 333159781Smlaier srch)->attr_info)); 334159781Smlaier srch++) ; 335159781Smlaier 336159781Smlaier context->search_index = srch; 337159781Smlaier if (cres) 338159781Smlaier return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object; 339159781Smlaier return NULL; 340159781Smlaier} 341159781Smlaier 342159781Smlaierstatic int mem_list_end(STORE *s, void *handle) 343159781Smlaier{ 344159781Smlaier struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 345159781Smlaier 346159781Smlaier if (!context) { 347159781Smlaier STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); 348159781Smlaier return 0; 349159781Smlaier } 350159781Smlaier if (context && context->search_attributes) 351159781Smlaier sk_STORE_ATTR_INFO_free(context->search_attributes); 352159781Smlaier if (context) 353159781Smlaier OPENSSL_free(context); 354159781Smlaier return 1; 355159781Smlaier} 356159781Smlaier 357159781Smlaierstatic int mem_list_endp(STORE *s, void *handle) 358159781Smlaier{ 359159781Smlaier struct mem_ctx_st *context = (struct mem_ctx_st *)handle; 360159781Smlaier 361159781Smlaier if (!context 362121470Sume || context->search_index 363186199Skmacy == sk_STORE_ATTR_INFO_num(context->search_attributes)) 364121470Sume return 1; 365186199Skmacy return 0; 366186199Skmacy} 367186199Skmacy 368186199Skmacystatic int mem_lock(STORE *s, OPENSSL_ITEM attributes[], 369186199Skmacy OPENSSL_ITEM parameters[]) 370186199Skmacy{ 371186199Skmacy return 1; 372186199Skmacy} 373186119Sqingli 374186199Skmacystatic int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], 375186199Skmacy OPENSSL_ITEM parameters[]) 376186199Skmacy{ 377136704Srwatson return 1; 378136704Srwatson} 379136704Srwatson 380136704Srwatsonstatic int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)) 381136704Srwatson{ 382136704Srwatson return 1; 383136704Srwatson} 384136704Srwatson