]> granicus.if.org Git - apache/blob - modules/ssl/ssl_engine_ds.c
replace ssl_ds_array usage with apr_array_header_t
[apache] / modules / ssl / ssl_engine_ds.c
1 /*                      _             _
2 **  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
3 ** | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
4 ** | | | | | | (_) | (_| |   \__ \__ \ |  www.modssl.org
5 ** |_| |_| |_|\___/ \__,_|___|___/___/_|  ftp.modssl.org
6 **                      |_____|
7 **  ssl_engine_ds.c
8 **  Additional Data Structures
9 */
10
11 /* ====================================================================
12  * The Apache Software License, Version 1.1
13  *
14  * Copyright (c) 2000-2001 The Apache Software Foundation.  All rights
15  * reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  *
21  * 1. Redistributions of source code must retain the above copyright
22  *    notice, this list of conditions and the following disclaimer.
23  *
24  * 2. Redistributions in binary form must reproduce the above copyright
25  *    notice, this list of conditions and the following disclaimer in
26  *    the documentation and/or other materials provided with the
27  *    distribution.
28  *
29  * 3. The end-user documentation included with the redistribution,
30  *    if any, must include the following acknowledgment:
31  *       "This product includes software developed by the
32  *        Apache Software Foundation (http://www.apache.org/)."
33  *    Alternately, this acknowledgment may appear in the software itself,
34  *    if and wherever such third-party acknowledgments normally appear.
35  *
36  * 4. The names "Apache" and "Apache Software Foundation" must
37  *    not be used to endorse or promote products derived from this
38  *    software without prior written permission. For written
39  *    permission, please contact apache@apache.org.
40  *
41  * 5. Products derived from this software may not be called "Apache",
42  *    nor may "Apache" appear in their name, without prior written
43  *    permission of the Apache Software Foundation.
44  *
45  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
46  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
47  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
48  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
49  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
51  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
52  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
54  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
55  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56  * SUCH DAMAGE.
57  * ====================================================================
58  */
59
60                              /* ``If you can't do it in
61                                   C or assembly language,
62                                   it isn't worth doing.''
63                                          -- Unknown         */
64 #include "mod_ssl.h"
65
66 /*  _________________________________________________________________
67 **
68 **  Data Structures which store _arbitrary_ data
69 **  _________________________________________________________________
70 */
71
72 ssl_ds_array *ssl_ds_array_make(apr_pool_t *p, int size)
73 {
74     ssl_ds_array *a;
75
76     if ((a = (ssl_ds_array *)apr_palloc(p, sizeof(ssl_ds_array))) == NULL)
77         return NULL;
78     a->pPool = p;
79     apr_pool_sub_make(&a->pSubPool, p, NULL);
80     if (a->pSubPool == NULL)
81         return NULL;
82     a->aData = apr_array_make(a->pSubPool, 2, size);
83     return a;
84 }
85
86 BOOL ssl_ds_array_isempty(ssl_ds_array *a)
87 {
88     if (a == NULL || a->aData == NULL || a->aData->nelts == 0)
89         return TRUE;
90     else
91         return FALSE;
92 }
93
94 void *ssl_ds_array_push(ssl_ds_array *a)
95 {
96     void *d;
97
98     d = (void *)apr_array_push(a->aData);
99     return d;
100 }
101
102 void *ssl_ds_array_get(ssl_ds_array *a, int n)
103 {
104     void *d;
105
106     if (n < 0 || n >= a->aData->nelts)
107         return NULL;
108     d = (void *)(a->aData->elts+(a->aData->elt_size*n));
109     return d;
110 }
111
112 void ssl_ds_array_wipeout(ssl_ds_array *a)
113 {
114     if (a->aData->nelts > 0)
115         memset(a->aData->elts, 0, a->aData->elt_size*a->aData->nelts);
116     return;
117 }
118
119 void ssl_ds_array_kill(ssl_ds_array *a)
120 {
121     apr_pool_destroy(a->pSubPool);
122     a->pSubPool = NULL;
123     a->aData    = NULL;
124     return;
125 }
126
127 ssl_ds_table *ssl_ds_table_make(apr_pool_t *p, int size)
128 {
129     ssl_ds_table *t;
130
131     if ((t = (ssl_ds_table *)apr_palloc(p, sizeof(ssl_ds_table))) == NULL)
132         return NULL;
133     t->pPool = p;
134     apr_pool_sub_make(&t->pSubPool, p, NULL);
135     if (t->pSubPool == NULL)
136         return NULL;
137     t->aKey  = apr_array_make(t->pSubPool, 2, MAX_STRING_LEN);
138     t->aData = apr_array_make(t->pSubPool, 2, size);
139     return t;
140 }
141
142 BOOL ssl_ds_table_isempty(ssl_ds_table *t)
143 {
144     if (t == NULL || t->aKey == NULL || t->aKey->nelts == 0)
145         return TRUE;
146     else
147         return FALSE;
148 }
149
150 void *ssl_ds_table_push(ssl_ds_table *t, char *key)
151 {
152     char *k;
153     void *d;
154
155     k = (char *)apr_array_push(t->aKey);
156     d = (void *)apr_array_push(t->aData);
157     apr_cpystrn(k, key, t->aKey->elt_size);
158     return d;
159 }
160
161 void *ssl_ds_table_get(ssl_ds_table *t, char *key)
162 {
163     char *k;
164     void *d;
165     int i;
166
167     d = NULL;
168     for (i = 0; i < t->aKey->nelts; i++) {
169         k = (t->aKey->elts+(t->aKey->elt_size*i));
170         if (strEQ(k, key)) {
171             d = (void *)(t->aData->elts+(t->aData->elt_size*i));
172             break;
173         }
174     }
175     return d;
176 }
177
178 void ssl_ds_table_wipeout(ssl_ds_table *t)
179 {
180     if (t->aKey->nelts > 0) {
181         memset(t->aKey->elts, 0, t->aKey->elt_size*t->aKey->nelts);
182         memset(t->aData->elts, 0, t->aData->elt_size*t->aData->nelts);
183     }
184     return;
185 }
186
187 void ssl_ds_table_kill(ssl_ds_table *t)
188 {
189     apr_pool_destroy(t->pSubPool);
190     t->pSubPool = NULL;
191     t->aKey     = NULL;
192     t->aData    = NULL;
193     return;
194 }
195
196 /*
197  * certain key and cert data needs to survive restarts,
198  * which are stored in the user data table of s->process->pool.
199  * to prevent "leaking" of this data, we use malloc/free
200  * rather than apr_palloc and these wrappers to help make sure
201  * we do not leak the malloc-ed data.
202  */
203 unsigned char *ssl_asn1_table_set(apr_hash_t *table,
204                                   const char *key,
205                                   long int length)
206 {
207     apr_ssize_t klen = strlen(key);
208     ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
209
210     /*
211      * if a value for this key already exists,
212      * reuse as much of the already malloc-ed data
213      * as possible.
214      */
215     if (asn1) {
216         if (asn1->nData != length) {
217             free(asn1->cpData); /* XXX: realloc? */
218             asn1->cpData = NULL;
219         }
220     }
221     else {
222         asn1 = malloc(sizeof(*asn1));
223         asn1->source_mtime = 0; /* used as a note for encrypted private keys */
224         asn1->cpData = NULL;
225     }
226
227     asn1->nData = length;
228     if (!asn1->cpData) {
229         asn1->cpData = malloc(length);
230     }
231
232     apr_hash_set(table, key, klen, asn1);
233
234     return asn1->cpData; /* caller will assign a value to this */
235 }
236
237 ssl_asn1_t *ssl_asn1_table_get(apr_hash_t *table,
238                                const char *key)
239 {
240     return (ssl_asn1_t *)apr_hash_get(table, key, APR_HASH_KEY_STRING);
241 }
242
243 void ssl_asn1_table_unset(apr_hash_t *table,
244                           const char *key)
245 {
246     apr_ssize_t klen = strlen(key);
247     ssl_asn1_t *asn1 = apr_hash_get(table, key, klen);
248
249     if (!asn1) {
250         return;
251     }
252
253     if (asn1->cpData) {
254         free(asn1->cpData);
255     }
256     free(asn1);
257
258     apr_hash_set(table, key, klen, NULL);
259 }