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