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 36 /* 37 * Should use two hash/tree certificates intead of a array. Criteria 38 * should be subject and subjectKeyIdentifier since those two are 39 * commonly seached on in CMS and path building. 40 */ 41 42 struct mem_data { 43 char *name; 44 struct { 45 unsigned long len; 46 hx509_cert *val; 47 } certs; 48 hx509_private_key *keys; 49 }; 50 51 static int 52 mem_init(hx509_context context, 53 hx509_certs certs, void **data, int flags, 54 const char *residue, hx509_lock lock) 55 { 56 struct mem_data *mem; 57 mem = calloc(1, sizeof(*mem)); 58 if (mem == NULL) 59 return ENOMEM; 60 if (residue == NULL || residue[0] == '\0') 61 residue = "anonymous"; 62 mem->name = strdup(residue); 63 if (mem->name == NULL) { 64 free(mem); 65 return ENOMEM; 66 } 67 *data = mem; 68 return 0; 69 } 70 71 static int 72 mem_free(hx509_certs certs, void *data) 73 { 74 struct mem_data *mem = data; 75 unsigned long i; 76 77 for (i = 0; i < mem->certs.len; i++) 78 hx509_cert_free(mem->certs.val[i]); 79 free(mem->certs.val); 80 for (i = 0; mem->keys && mem->keys[i]; i++) 81 hx509_private_key_free(&mem->keys[i]); 82 free(mem->keys); 83 free(mem->name); 84 free(mem); 85 86 return 0; 87 } 88 89 static int 90 mem_add(hx509_context context, hx509_certs certs, void *data, hx509_cert c) 91 { 92 struct mem_data *mem = data; 93 hx509_cert *val; 94 95 val = realloc(mem->certs.val, 96 (mem->certs.len + 1) * sizeof(mem->certs.val[0])); 97 if (val == NULL) 98 return ENOMEM; 99 100 mem->certs.val = val; 101 mem->certs.val[mem->certs.len] = hx509_cert_ref(c); 102 mem->certs.len++; 103 104 return 0; 105 } 106 107 static int 108 mem_iter_start(hx509_context context, 109 hx509_certs certs, 110 void *data, 111 void **cursor) 112 { 113 unsigned long *iter = malloc(sizeof(*iter)); 114 115 if (iter == NULL) 116 return ENOMEM; 117 118 *iter = 0; 119 *cursor = iter; 120 121 return 0; 122 } 123 124 static int 125 mem_iter(hx509_context contexst, 126 hx509_certs certs, 127 void *data, 128 void *cursor, 129 hx509_cert *cert) 130 { 131 unsigned long *iter = cursor; 132 struct mem_data *mem = data; 133 134 if (*iter >= mem->certs.len) { 135 *cert = NULL; 136 return 0; 137 } 138 139 *cert = hx509_cert_ref(mem->certs.val[*iter]); 140 (*iter)++; 141 return 0; 142 } 143 144 static int 145 mem_iter_end(hx509_context context, 146 hx509_certs certs, 147 void *data, 148 void *cursor) 149 { 150 free(cursor); 151 return 0; 152 } 153 154 static int 155 mem_getkeys(hx509_context context, 156 hx509_certs certs, 157 void *data, 158 hx509_private_key **keys) 159 { 160 struct mem_data *mem = data; 161 int i; 162 163 for (i = 0; mem->keys && mem->keys[i]; i++) 164 ; 165 *keys = calloc(i + 1, sizeof(**keys)); 166 for (i = 0; mem->keys && mem->keys[i]; i++) { 167 (*keys)[i] = _hx509_private_key_ref(mem->keys[i]); 168 if ((*keys)[i] == NULL) { 169 while (--i >= 0) 170 hx509_private_key_free(&(*keys)[i]); 171 hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 172 return ENOMEM; 173 } 174 } 175 (*keys)[i] = NULL; 176 return 0; 177 } 178 179 static int 180 mem_addkey(hx509_context context, 181 hx509_certs certs, 182 void *data, 183 hx509_private_key key) 184 { 185 struct mem_data *mem = data; 186 void *ptr; 187 int i; 188 189 for (i = 0; mem->keys && mem->keys[i]; i++) 190 ; 191 ptr = realloc(mem->keys, (i + 2) * sizeof(*mem->keys)); 192 if (ptr == NULL) { 193 hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 194 return ENOMEM; 195 } 196 mem->keys = ptr; 197 mem->keys[i] = _hx509_private_key_ref(key); 198 mem->keys[i + 1] = NULL; 199 return 0; 200 } 201 202 203 static struct hx509_keyset_ops keyset_mem = { 204 "MEMORY", 205 0, 206 mem_init, 207 NULL, 208 mem_free, 209 mem_add, 210 NULL, 211 mem_iter_start, 212 mem_iter, 213 mem_iter_end, 214 NULL, 215 mem_getkeys, 216 mem_addkey 217 }; 218 219 void 220 _hx509_ks_mem_register(hx509_context context) 221 { 222 _hx509_ks_register(context, &keyset_mem); 223 } 224