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" 35 RCSID("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 43 struct mem_data { 44 char *name; 45 struct { 46 unsigned long len; 47 hx509_cert *val; 48 } certs; 49 hx509_private_key *keys; 50 }; 51 52 static int 53 mem_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 72 static int 73 mem_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 90 static int 91 mem_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 108 static int 109 mem_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 125 static int 126 mem_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 145 static int 146 mem_iter_end(hx509_context context, 147 hx509_certs certs, 148 void *data, 149 void *cursor) 150 { 151 free(cursor); 152 return 0; 153 } 154 155 static int 156 mem_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 180 static int 181 mem_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 204 static 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 220 void 221 _hx509_ks_mem_register(hx509_context context) 222 { 223 _hx509_ks_register(context, &keyset_mem); 224 } 225