1178825Sdfr/* 2178825Sdfr * Copyright (c) 2005 - 2006 Kungliga Tekniska H�gskolan 3178825Sdfr * (Royal Institute of Technology, Stockholm, Sweden). 4178825Sdfr * All rights reserved. 5178825Sdfr * 6178825Sdfr * Redistribution and use in source and binary forms, with or without 7178825Sdfr * modification, are permitted provided that the following conditions 8178825Sdfr * are met: 9178825Sdfr * 10178825Sdfr * 1. Redistributions of source code must retain the above copyright 11178825Sdfr * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13178825Sdfr * 2. Redistributions in binary form must reproduce the above copyright 14178825Sdfr * notice, this list of conditions and the following disclaimer in the 15178825Sdfr * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17178825Sdfr * 3. Neither the name of the Institute nor the names of its contributors 18178825Sdfr * may be used to endorse or promote products derived from this software 19178825Sdfr * without specific prior written permission. 20178825Sdfr * 21178825Sdfr * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22178825Sdfr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24178825Sdfr * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25178825Sdfr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26178825Sdfr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27178825Sdfr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28178825Sdfr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29178825Sdfr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30178825Sdfr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31178825Sdfr * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34178825Sdfr#include "hx_locl.h" 35178825SdfrRCSID("Id$"); 36178825Sdfr 37178825Sdfr/* 38178825Sdfr * Should use two hash/tree certificates intead of a array. Criteria 39178825Sdfr * should be subject and subjectKeyIdentifier since those two are 40178825Sdfr * commonly seached on in CMS and path building. 41178825Sdfr */ 42178825Sdfr 43178825Sdfrstruct mem_data { 44178825Sdfr char *name; 45178825Sdfr struct { 46178825Sdfr unsigned long len; 47178825Sdfr hx509_cert *val; 48178825Sdfr } certs; 49178825Sdfr hx509_private_key *keys; 50178825Sdfr}; 51178825Sdfr 52178825Sdfrstatic int 53178825Sdfrmem_init(hx509_context context, 54178825Sdfr hx509_certs certs, void **data, int flags, 55178825Sdfr const char *residue, hx509_lock lock) 56178825Sdfr{ 57178825Sdfr struct mem_data *mem; 58178825Sdfr mem = calloc(1, sizeof(*mem)); 59178825Sdfr if (mem == NULL) 60178825Sdfr return ENOMEM; 61178825Sdfr if (residue == NULL || residue[0] == '\0') 62178825Sdfr residue = "anonymous"; 63178825Sdfr mem->name = strdup(residue); 64178825Sdfr if (mem->name == NULL) { 65178825Sdfr free(mem); 66178825Sdfr return ENOMEM; 67178825Sdfr } 68178825Sdfr *data = mem; 69178825Sdfr return 0; 70178825Sdfr} 71178825Sdfr 72178825Sdfrstatic int 73178825Sdfrmem_free(hx509_certs certs, void *data) 74178825Sdfr{ 75178825Sdfr struct mem_data *mem = data; 76178825Sdfr unsigned long i; 77178825Sdfr 78178825Sdfr for (i = 0; i < mem->certs.len; i++) 79178825Sdfr hx509_cert_free(mem->certs.val[i]); 80178825Sdfr free(mem->certs.val); 81178825Sdfr for (i = 0; mem->keys && mem->keys[i]; i++) 82178825Sdfr _hx509_private_key_free(&mem->keys[i]); 83178825Sdfr free(mem->keys); 84178825Sdfr free(mem->name); 85178825Sdfr free(mem); 86178825Sdfr 87178825Sdfr return 0; 88178825Sdfr} 89178825Sdfr 90178825Sdfrstatic int 91178825Sdfrmem_add(hx509_context context, hx509_certs certs, void *data, hx509_cert c) 92178825Sdfr{ 93178825Sdfr struct mem_data *mem = data; 94178825Sdfr hx509_cert *val; 95178825Sdfr 96178825Sdfr val = realloc(mem->certs.val, 97178825Sdfr (mem->certs.len + 1) * sizeof(mem->certs.val[0])); 98178825Sdfr if (val == NULL) 99178825Sdfr return ENOMEM; 100178825Sdfr 101178825Sdfr mem->certs.val = val; 102178825Sdfr mem->certs.val[mem->certs.len] = hx509_cert_ref(c); 103178825Sdfr mem->certs.len++; 104178825Sdfr 105178825Sdfr return 0; 106178825Sdfr} 107178825Sdfr 108178825Sdfrstatic int 109178825Sdfrmem_iter_start(hx509_context context, 110178825Sdfr hx509_certs certs, 111178825Sdfr void *data, 112178825Sdfr void **cursor) 113178825Sdfr{ 114178825Sdfr unsigned long *iter = malloc(sizeof(*iter)); 115178825Sdfr 116178825Sdfr if (iter == NULL) 117178825Sdfr return ENOMEM; 118178825Sdfr 119178825Sdfr *iter = 0; 120178825Sdfr *cursor = iter; 121178825Sdfr 122178825Sdfr return 0; 123178825Sdfr} 124178825Sdfr 125178825Sdfrstatic int 126178825Sdfrmem_iter(hx509_context contexst, 127178825Sdfr hx509_certs certs, 128178825Sdfr void *data, 129178825Sdfr void *cursor, 130178825Sdfr hx509_cert *cert) 131178825Sdfr{ 132178825Sdfr unsigned long *iter = cursor; 133178825Sdfr struct mem_data *mem = data; 134178825Sdfr 135178825Sdfr if (*iter >= mem->certs.len) { 136178825Sdfr *cert = NULL; 137178825Sdfr return 0; 138178825Sdfr } 139178825Sdfr 140178825Sdfr *cert = hx509_cert_ref(mem->certs.val[*iter]); 141178825Sdfr (*iter)++; 142178825Sdfr return 0; 143178825Sdfr} 144178825Sdfr 145178825Sdfrstatic int 146178825Sdfrmem_iter_end(hx509_context context, 147178825Sdfr hx509_certs certs, 148178825Sdfr void *data, 149178825Sdfr void *cursor) 150178825Sdfr{ 151178825Sdfr free(cursor); 152178825Sdfr return 0; 153178825Sdfr} 154178825Sdfr 155178825Sdfrstatic int 156178825Sdfrmem_getkeys(hx509_context context, 157178825Sdfr hx509_certs certs, 158178825Sdfr void *data, 159178825Sdfr hx509_private_key **keys) 160178825Sdfr{ 161178825Sdfr struct mem_data *mem = data; 162178825Sdfr int i; 163178825Sdfr 164178825Sdfr for (i = 0; mem->keys && mem->keys[i]; i++) 165178825Sdfr ; 166178825Sdfr *keys = calloc(i + 1, sizeof(**keys)); 167178825Sdfr for (i = 0; mem->keys && mem->keys[i]; i++) { 168178825Sdfr (*keys)[i] = _hx509_private_key_ref(mem->keys[i]); 169178825Sdfr if ((*keys)[i] == NULL) { 170178825Sdfr while (--i >= 0) 171178825Sdfr _hx509_private_key_free(&(*keys)[i]); 172178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 173178825Sdfr return ENOMEM; 174178825Sdfr } 175178825Sdfr } 176178825Sdfr (*keys)[i] = NULL; 177178825Sdfr return 0; 178178825Sdfr} 179178825Sdfr 180178825Sdfrstatic int 181178825Sdfrmem_addkey(hx509_context context, 182178825Sdfr hx509_certs certs, 183178825Sdfr void *data, 184178825Sdfr hx509_private_key key) 185178825Sdfr{ 186178825Sdfr struct mem_data *mem = data; 187178825Sdfr void *ptr; 188178825Sdfr int i; 189178825Sdfr 190178825Sdfr for (i = 0; mem->keys && mem->keys[i]; i++) 191178825Sdfr ; 192178825Sdfr ptr = realloc(mem->keys, (i + 2) * sizeof(*mem->keys)); 193178825Sdfr if (ptr == NULL) { 194178825Sdfr hx509_set_error_string(context, 0, ENOMEM, "out of memory"); 195178825Sdfr return ENOMEM; 196178825Sdfr } 197178825Sdfr mem->keys = ptr; 198178825Sdfr mem->keys[i++] = _hx509_private_key_ref(key); 199178825Sdfr mem->keys[i++] = NULL; 200178825Sdfr return 0; 201178825Sdfr} 202178825Sdfr 203178825Sdfr 204178825Sdfrstatic struct hx509_keyset_ops keyset_mem = { 205178825Sdfr "MEMORY", 206178825Sdfr 0, 207178825Sdfr mem_init, 208178825Sdfr NULL, 209178825Sdfr mem_free, 210178825Sdfr mem_add, 211178825Sdfr NULL, 212178825Sdfr mem_iter_start, 213178825Sdfr mem_iter, 214178825Sdfr mem_iter_end, 215178825Sdfr NULL, 216178825Sdfr mem_getkeys, 217178825Sdfr mem_addkey 218178825Sdfr}; 219178825Sdfr 220178825Sdfrvoid 221178825Sdfr_hx509_ks_mem_register(hx509_context context) 222178825Sdfr{ 223178825Sdfr _hx509_ks_register(context, &keyset_mem); 224178825Sdfr} 225