1/* 2 * Copyright (c) 2005 - 2006 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include "hx_locl.h" 35RCSID("Id$"); 36 37/* 38 * Should use two hash/tree certificates intead of a array. Criteria 39 * should be subject and subjectKeyIdentifier since those two are 40 * commonly seached on in CMS and path building. 41 */ 42 43struct mem_data { 44 char *name; 45 struct { 46 unsigned long len; 47 hx509_cert *val; 48 } certs; 49 hx509_private_key *keys; 50}; 51 52static int 53mem_init(hx509_context context, 54 hx509_certs certs, void **data, int flags, 55 const char *residue, hx509_lock lock) 56{ 57 struct mem_data *mem; 58 mem = calloc(1, sizeof(*mem)); 59 if (mem == NULL) 60 return ENOMEM; 61 if (residue == NULL || residue[0] == '\0') 62 residue = "anonymous"; 63 mem->name = strdup(residue); 64 if (mem->name == NULL) { 65 free(mem); 66 return ENOMEM; 67 } 68 *data = mem; 69 return 0; 70} 71 72static int 73mem_free(hx509_certs certs, void *data) 74{ 75 struct mem_data *mem = data; 76 unsigned long i; 77 78 for (i = 0; i < mem->certs.len; i++) 79 hx509_cert_free(mem->certs.val[i]); 80 free(mem->certs.val); 81 for (i = 0; mem->keys && mem->keys[i]; i++) 82 _hx509_private_key_free(&mem->keys[i]); 83 free(mem->keys); 84 free(mem->name); 85 free(mem); 86 87 return 0; 88} 89 90static int 91mem_add(hx509_context context, hx509_certs certs, void *data, hx509_cert c) 92{ 93 struct mem_data *mem = data; 94 hx509_cert *val; 95 96 val = realloc(mem->certs.val, 97 (mem->certs.len + 1) * sizeof(mem->certs.val[0])); 98 if (val == NULL) 99 return ENOMEM; 100 101 mem->certs.val = val; 102 mem->certs.val[mem->certs.len] = hx509_cert_ref(c); 103 mem->certs.len++; 104 105 return 0; 106} 107 108static int 109mem_iter_start(hx509_context context, 110 hx509_certs certs, 111 void *data, 112 void **cursor) 113{ 114 unsigned long *iter = malloc(sizeof(*iter)); 115 116 if (iter == NULL) 117 return ENOMEM; 118 119 *iter = 0; 120 *cursor = iter; 121 122 return 0; 123} 124 125static int 126mem_iter(hx509_context contexst, 127 hx509_certs certs, 128 void *data, 129 void *cursor, 130 hx509_cert *cert) 131{ 132 unsigned long *iter = cursor; 133 struct mem_data *mem = data; 134 135 if (*iter >= mem->certs.len) { 136 *cert = NULL; 137 return 0; 138 } 139 140 *cert = hx509_cert_ref(mem->certs.val[*iter]); 141 (*iter)++; 142 return 0; 143} 144 145static int 146mem_iter_end(hx509_context context, 147 hx509_certs certs, 148 void *data, 149 void *cursor) 150{ 151 free(cursor); 152 return 0; 153} 154 155static int 156mem_getkeys(hx509_context context, 157 hx509_certs certs, 158 void *data, 159 hx509_private_key **keys) 160{ 161 struct mem_data *mem = data; 162 int i; 163 164 for (i = 0; mem->keys && mem->keys[i]; i++) 165 ; 166 *keys = calloc(i + 1, sizeof(**keys)); 167 for (i = 0; mem->keys && mem->keys[i]; i++) { 168 (*keys)[i] = _hx509_private_key_ref(mem->keys[i]); 169 if ((*keys)[i] == NULL) { 170 while (--i >= 0) 171 _hx509_private_key_free(&(*keys)[i]); 172 hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 173 return ENOMEM; 174 } 175 } 176 (*keys)[i] = NULL; 177 return 0; 178} 179 180static int 181mem_addkey(hx509_context context, 182 hx509_certs certs, 183 void *data, 184 hx509_private_key key) 185{ 186 struct mem_data *mem = data; 187 void *ptr; 188 int i; 189 190 for (i = 0; mem->keys && mem->keys[i]; i++) 191 ; 192 ptr = realloc(mem->keys, (i + 2) * sizeof(*mem->keys)); 193 if (ptr == NULL) { 194 hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 195 return ENOMEM; 196 } 197 mem->keys = ptr; 198 mem->keys[i++] = _hx509_private_key_ref(key); 199 mem->keys[i++] = NULL; 200 return 0; 201} 202 203 204static struct hx509_keyset_ops keyset_mem = { 205 "MEMORY", 206 0, 207 mem_init, 208 NULL, 209 mem_free, 210 mem_add, 211 NULL, 212 mem_iter_start, 213 mem_iter, 214 mem_iter_end, 215 NULL, 216 mem_getkeys, 217 mem_addkey 218}; 219 220void 221_hx509_ks_mem_register(hx509_context context) 222{ 223 _hx509_ks_register(context, &keyset_mem); 224} 225