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