1 1.1 elric /* $NetBSD: keyset.c,v 1.2 2017/01/28 21:31:48 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (c) 2004 - 2007 Kungliga Tekniska Hgskolan 5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden). 6 1.1 elric * All rights reserved. 7 1.1 elric * 8 1.1 elric * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 9 1.1 elric * 10 1.1 elric * Redistribution and use in source and binary forms, with or without 11 1.1 elric * modification, are permitted provided that the following conditions 12 1.1 elric * are met: 13 1.1 elric * 14 1.1 elric * 1. Redistributions of source code must retain the above copyright 15 1.1 elric * notice, this list of conditions and the following disclaimer. 16 1.1 elric * 17 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 elric * notice, this list of conditions and the following disclaimer in the 19 1.1 elric * documentation and/or other materials provided with the distribution. 20 1.1 elric * 21 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors 22 1.1 elric * may be used to endorse or promote products derived from this software 23 1.1 elric * without specific prior written permission. 24 1.1 elric * 25 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 26 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 29 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 1.1 elric * SUCH DAMAGE. 36 1.1 elric */ 37 1.1 elric 38 1.1 elric #include "hx_locl.h" 39 1.1 elric 40 1.1 elric /** 41 1.1 elric * @page page_keyset Certificate store operations 42 1.1 elric * 43 1.1 elric * Type of certificates store: 44 1.1 elric * - MEMORY 45 1.1 elric * In memory based format. Doesnt support storing. 46 1.1 elric * - FILE 47 1.1 elric * FILE supports raw DER certicates and PEM certicates. When PEM is 48 1.1 elric * used the file can contain may certificates and match private 49 1.1 elric * keys. Support storing the certificates. DER format only supports 50 1.1 elric * on certificate and no private key. 51 1.1 elric * - PEM-FILE 52 1.1 elric * Same as FILE, defaulting to PEM encoded certificates. 53 1.1 elric * - PEM-FILE 54 1.1 elric * Same as FILE, defaulting to DER encoded certificates. 55 1.1 elric * - PKCS11 56 1.1 elric * - PKCS12 57 1.1 elric * - DIR 58 1.1 elric * - KEYCHAIN 59 1.1 elric * Apple Mac OS X KeyChain backed keychain object. 60 1.1 elric * 61 1.1 elric * See the library functions here: @ref hx509_keyset 62 1.1 elric */ 63 1.1 elric 64 1.1 elric struct hx509_certs_data { 65 1.1 elric unsigned int ref; 66 1.1 elric struct hx509_keyset_ops *ops; 67 1.1 elric void *ops_data; 68 1.1 elric }; 69 1.1 elric 70 1.1 elric static struct hx509_keyset_ops * 71 1.1 elric _hx509_ks_type(hx509_context context, const char *type) 72 1.1 elric { 73 1.1 elric int i; 74 1.1 elric 75 1.1 elric for (i = 0; i < context->ks_num_ops; i++) 76 1.1 elric if (strcasecmp(type, context->ks_ops[i]->name) == 0) 77 1.1 elric return context->ks_ops[i]; 78 1.1 elric 79 1.1 elric return NULL; 80 1.1 elric } 81 1.1 elric 82 1.1 elric void 83 1.1 elric _hx509_ks_register(hx509_context context, struct hx509_keyset_ops *ops) 84 1.1 elric { 85 1.1 elric struct hx509_keyset_ops **val; 86 1.1 elric 87 1.1 elric if (_hx509_ks_type(context, ops->name)) 88 1.1 elric return; 89 1.1 elric 90 1.1 elric val = realloc(context->ks_ops, 91 1.1 elric (context->ks_num_ops + 1) * sizeof(context->ks_ops[0])); 92 1.1 elric if (val == NULL) 93 1.1 elric return; 94 1.1 elric val[context->ks_num_ops] = ops; 95 1.1 elric context->ks_ops = val; 96 1.1 elric context->ks_num_ops++; 97 1.1 elric } 98 1.1 elric 99 1.1 elric /** 100 1.1 elric * Open or creates a new hx509 certificate store. 101 1.1 elric * 102 1.1 elric * @param context A hx509 context 103 1.1 elric * @param name name of the store, format is TYPE:type-specific-string, 104 1.1 elric * if NULL is used the MEMORY store is used. 105 1.1 elric * @param flags list of flags: 106 1.1 elric * - HX509_CERTS_CREATE create a new keystore of the specific TYPE. 107 1.1 elric * - HX509_CERTS_UNPROTECT_ALL fails if any private key failed to be extracted. 108 1.1 elric * @param lock a lock that unlocks the certificates store, use NULL to 109 1.1 elric * select no password/certifictes/prompt lock (see @ref page_lock). 110 1.1 elric * @param certs return pointer, free with hx509_certs_free(). 111 1.1 elric * 112 1.2 christos * @return Returns an hx509 error code. 113 1.2 christos * 114 1.1 elric * @ingroup hx509_keyset 115 1.1 elric */ 116 1.1 elric 117 1.1 elric int 118 1.1 elric hx509_certs_init(hx509_context context, 119 1.1 elric const char *name, int flags, 120 1.1 elric hx509_lock lock, hx509_certs *certs) 121 1.1 elric { 122 1.1 elric struct hx509_keyset_ops *ops; 123 1.1 elric const char *residue; 124 1.1 elric hx509_certs c; 125 1.1 elric char *type; 126 1.1 elric int ret; 127 1.1 elric 128 1.1 elric *certs = NULL; 129 1.1 elric 130 1.1 elric residue = strchr(name, ':'); 131 1.1 elric if (residue) { 132 1.1 elric type = malloc(residue - name + 1); 133 1.1 elric if (type) 134 1.1 elric strlcpy(type, name, residue - name + 1); 135 1.1 elric residue++; 136 1.1 elric if (residue[0] == '\0') 137 1.1 elric residue = NULL; 138 1.1 elric } else { 139 1.1 elric type = strdup("MEMORY"); 140 1.1 elric residue = name; 141 1.1 elric } 142 1.1 elric if (type == NULL) { 143 1.1 elric hx509_clear_error_string(context); 144 1.1 elric return ENOMEM; 145 1.1 elric } 146 1.1 elric 147 1.1 elric ops = _hx509_ks_type(context, type); 148 1.1 elric if (ops == NULL) { 149 1.1 elric hx509_set_error_string(context, 0, ENOENT, 150 1.1 elric "Keyset type %s is not supported", type); 151 1.1 elric free(type); 152 1.1 elric return ENOENT; 153 1.1 elric } 154 1.1 elric free(type); 155 1.1 elric c = calloc(1, sizeof(*c)); 156 1.1 elric if (c == NULL) { 157 1.1 elric hx509_clear_error_string(context); 158 1.1 elric return ENOMEM; 159 1.1 elric } 160 1.1 elric c->ops = ops; 161 1.1 elric c->ref = 1; 162 1.1 elric 163 1.1 elric ret = (*ops->init)(context, c, &c->ops_data, flags, residue, lock); 164 1.1 elric if (ret) { 165 1.1 elric free(c); 166 1.1 elric return ret; 167 1.1 elric } 168 1.1 elric 169 1.1 elric *certs = c; 170 1.1 elric return 0; 171 1.1 elric } 172 1.1 elric 173 1.1 elric /** 174 1.1 elric * Write the certificate store to stable storage. 175 1.1 elric * 176 1.1 elric * @param context A hx509 context. 177 1.1 elric * @param certs a certificate store to store. 178 1.1 elric * @param flags currently unused, use 0. 179 1.1 elric * @param lock a lock that unlocks the certificates store, use NULL to 180 1.1 elric * select no password/certifictes/prompt lock (see @ref page_lock). 181 1.1 elric * 182 1.1 elric * @return Returns an hx509 error code. HX509_UNSUPPORTED_OPERATION if 183 1.1 elric * the certificate store doesn't support the store operation. 184 1.1 elric * 185 1.1 elric * @ingroup hx509_keyset 186 1.1 elric */ 187 1.1 elric 188 1.1 elric int 189 1.1 elric hx509_certs_store(hx509_context context, 190 1.1 elric hx509_certs certs, 191 1.1 elric int flags, 192 1.1 elric hx509_lock lock) 193 1.1 elric { 194 1.1 elric if (certs->ops->store == NULL) { 195 1.1 elric hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION, 196 1.1 elric "keystore if type %s doesn't support " 197 1.1 elric "store operation", 198 1.1 elric certs->ops->name); 199 1.1 elric return HX509_UNSUPPORTED_OPERATION; 200 1.1 elric } 201 1.1 elric 202 1.1 elric return (*certs->ops->store)(context, certs, certs->ops_data, flags, lock); 203 1.1 elric } 204 1.1 elric 205 1.1 elric 206 1.1 elric hx509_certs 207 1.1 elric hx509_certs_ref(hx509_certs certs) 208 1.1 elric { 209 1.1 elric if (certs == NULL) 210 1.1 elric return NULL; 211 1.1 elric if (certs->ref == 0) 212 1.1 elric _hx509_abort("certs refcount == 0 on ref"); 213 1.1 elric if (certs->ref == UINT_MAX) 214 1.1 elric _hx509_abort("certs refcount == UINT_MAX on ref"); 215 1.1 elric certs->ref++; 216 1.1 elric return certs; 217 1.1 elric } 218 1.1 elric 219 1.1 elric /** 220 1.1 elric * Free a certificate store. 221 1.1 elric * 222 1.1 elric * @param certs certificate store to free. 223 1.1 elric * 224 1.1 elric * @ingroup hx509_keyset 225 1.1 elric */ 226 1.1 elric 227 1.1 elric void 228 1.1 elric hx509_certs_free(hx509_certs *certs) 229 1.1 elric { 230 1.1 elric if (*certs) { 231 1.1 elric if ((*certs)->ref == 0) 232 1.1 elric _hx509_abort("cert refcount == 0 on free"); 233 1.1 elric if (--(*certs)->ref > 0) 234 1.1 elric return; 235 1.1 elric 236 1.1 elric (*(*certs)->ops->free)(*certs, (*certs)->ops_data); 237 1.1 elric free(*certs); 238 1.1 elric *certs = NULL; 239 1.1 elric } 240 1.1 elric } 241 1.1 elric 242 1.1 elric /** 243 1.1 elric * Start the integration 244 1.1 elric * 245 1.1 elric * @param context a hx509 context. 246 1.1 elric * @param certs certificate store to iterate over 247 1.1 elric * @param cursor cursor that will keep track of progress, free with 248 1.1 elric * hx509_certs_end_seq(). 249 1.1 elric * 250 1.1 elric * @return Returns an hx509 error code. HX509_UNSUPPORTED_OPERATION is 251 1.1 elric * returned if the certificate store doesn't support the iteration 252 1.1 elric * operation. 253 1.1 elric * 254 1.1 elric * @ingroup hx509_keyset 255 1.1 elric */ 256 1.1 elric 257 1.1 elric int 258 1.1 elric hx509_certs_start_seq(hx509_context context, 259 1.1 elric hx509_certs certs, 260 1.1 elric hx509_cursor *cursor) 261 1.1 elric { 262 1.1 elric int ret; 263 1.1 elric 264 1.1 elric if (certs->ops->iter_start == NULL) { 265 1.1 elric hx509_set_error_string(context, 0, HX509_UNSUPPORTED_OPERATION, 266 1.1 elric "Keyset type %s doesn't support iteration", 267 1.1 elric certs->ops->name); 268 1.1 elric return HX509_UNSUPPORTED_OPERATION; 269 1.1 elric } 270 1.1 elric 271 1.1 elric ret = (*certs->ops->iter_start)(context, certs, certs->ops_data, cursor); 272 1.1 elric if (ret) 273 1.1 elric return ret; 274 1.1 elric 275 1.1 elric return 0; 276 1.1 elric } 277 1.1 elric 278 1.1 elric /** 279 1.1 elric * Get next ceritificate from the certificate keystore pointed out by 280 1.1 elric * cursor. 281 1.1 elric * 282 1.1 elric * @param context a hx509 context. 283 1.1 elric * @param certs certificate store to iterate over. 284 1.1 elric * @param cursor cursor that keeps track of progress. 285 1.1 elric * @param cert return certificate next in store, NULL if the store 286 1.1 elric * contains no more certificates. Free with hx509_cert_free(). 287 1.1 elric * 288 1.1 elric * @return Returns an hx509 error code. 289 1.1 elric * 290 1.1 elric * @ingroup hx509_keyset 291 1.1 elric */ 292 1.1 elric 293 1.1 elric int 294 1.1 elric hx509_certs_next_cert(hx509_context context, 295 1.1 elric hx509_certs certs, 296 1.1 elric hx509_cursor cursor, 297 1.1 elric hx509_cert *cert) 298 1.1 elric { 299 1.1 elric *cert = NULL; 300 1.1 elric return (*certs->ops->iter)(context, certs, certs->ops_data, cursor, cert); 301 1.1 elric } 302 1.1 elric 303 1.1 elric /** 304 1.1 elric * End the iteration over certificates. 305 1.1 elric * 306 1.1 elric * @param context a hx509 context. 307 1.1 elric * @param certs certificate store to iterate over. 308 1.1 elric * @param cursor cursor that will keep track of progress, freed. 309 1.1 elric * 310 1.1 elric * @return Returns an hx509 error code. 311 1.1 elric * 312 1.1 elric * @ingroup hx509_keyset 313 1.1 elric */ 314 1.1 elric 315 1.1 elric int 316 1.1 elric hx509_certs_end_seq(hx509_context context, 317 1.1 elric hx509_certs certs, 318 1.1 elric hx509_cursor cursor) 319 1.1 elric { 320 1.1 elric (*certs->ops->iter_end)(context, certs, certs->ops_data, cursor); 321 1.1 elric return 0; 322 1.1 elric } 323 1.1 elric 324 1.1 elric /** 325 1.2 christos * Iterate over all certificates in a keystore and call a function 326 1.2 christos * for each of them. 327 1.1 elric * 328 1.1 elric * @param context a hx509 context. 329 1.1 elric * @param certs certificate store to iterate over. 330 1.1 elric * @param func function to call for each certificate. The function 331 1.1 elric * should return non-zero to abort the iteration, that value is passed 332 1.1 elric * back to the caller of hx509_certs_iter_f(). 333 1.1 elric * @param ctx context variable that will passed to the function. 334 1.1 elric * 335 1.1 elric * @return Returns an hx509 error code. 336 1.1 elric * 337 1.1 elric * @ingroup hx509_keyset 338 1.1 elric */ 339 1.1 elric 340 1.1 elric int 341 1.1 elric hx509_certs_iter_f(hx509_context context, 342 1.1 elric hx509_certs certs, 343 1.1 elric int (*func)(hx509_context, void *, hx509_cert), 344 1.1 elric void *ctx) 345 1.1 elric { 346 1.1 elric hx509_cursor cursor; 347 1.1 elric hx509_cert c; 348 1.1 elric int ret; 349 1.1 elric 350 1.1 elric ret = hx509_certs_start_seq(context, certs, &cursor); 351 1.1 elric if (ret) 352 1.1 elric return ret; 353 1.1 elric 354 1.1 elric while (1) { 355 1.1 elric ret = hx509_certs_next_cert(context, certs, cursor, &c); 356 1.1 elric if (ret) 357 1.1 elric break; 358 1.1 elric if (c == NULL) { 359 1.1 elric ret = 0; 360 1.1 elric break; 361 1.1 elric } 362 1.1 elric ret = (*func)(context, ctx, c); 363 1.1 elric hx509_cert_free(c); 364 1.1 elric if (ret) 365 1.1 elric break; 366 1.1 elric } 367 1.1 elric 368 1.1 elric hx509_certs_end_seq(context, certs, cursor); 369 1.1 elric 370 1.1 elric return ret; 371 1.1 elric } 372 1.1 elric 373 1.1 elric #ifdef __BLOCKS__ 374 1.1 elric 375 1.1 elric static int 376 1.1 elric certs_iter(hx509_context context, void *ctx, hx509_cert cert) 377 1.1 elric { 378 1.1 elric int (^func)(hx509_cert) = ctx; 379 1.1 elric return func(cert); 380 1.1 elric } 381 1.1 elric 382 1.1 elric /** 383 1.2 christos * Iterate over all certificates in a keystore and call a block 384 1.2 christos * for each of them. 385 1.1 elric * 386 1.1 elric * @param context a hx509 context. 387 1.1 elric * @param certs certificate store to iterate over. 388 1.1 elric * @param func block to call for each certificate. The function 389 1.1 elric * should return non-zero to abort the iteration, that value is passed 390 1.1 elric * back to the caller of hx509_certs_iter(). 391 1.1 elric * 392 1.1 elric * @return Returns an hx509 error code. 393 1.1 elric * 394 1.1 elric * @ingroup hx509_keyset 395 1.1 elric */ 396 1.1 elric 397 1.1 elric int 398 1.1 elric hx509_certs_iter(hx509_context context, 399 1.1 elric hx509_certs certs, 400 1.1 elric int (^func)(hx509_cert)) 401 1.1 elric { 402 1.1 elric return hx509_certs_iter_f(context, certs, certs_iter, func); 403 1.1 elric } 404 1.1 elric #endif 405 1.1 elric 406 1.1 elric 407 1.1 elric /** 408 1.1 elric * Function to use to hx509_certs_iter_f() as a function argument, the 409 1.1 elric * ctx variable to hx509_certs_iter_f() should be a FILE file descriptor. 410 1.1 elric * 411 1.1 elric * @param context a hx509 context. 412 1.1 elric * @param ctx used by hx509_certs_iter_f(). 413 1.1 elric * @param c a certificate 414 1.1 elric * 415 1.1 elric * @return Returns an hx509 error code. 416 1.1 elric * 417 1.1 elric * @ingroup hx509_keyset 418 1.1 elric */ 419 1.1 elric 420 1.1 elric int 421 1.1 elric hx509_ci_print_names(hx509_context context, void *ctx, hx509_cert c) 422 1.1 elric { 423 1.1 elric Certificate *cert; 424 1.1 elric hx509_name n; 425 1.1 elric char *s, *i; 426 1.1 elric 427 1.1 elric cert = _hx509_get_cert(c); 428 1.1 elric 429 1.1 elric _hx509_name_from_Name(&cert->tbsCertificate.subject, &n); 430 1.1 elric hx509_name_to_string(n, &s); 431 1.1 elric hx509_name_free(&n); 432 1.1 elric _hx509_name_from_Name(&cert->tbsCertificate.issuer, &n); 433 1.1 elric hx509_name_to_string(n, &i); 434 1.1 elric hx509_name_free(&n); 435 1.1 elric fprintf(ctx, "subject: %s\nissuer: %s\n", s, i); 436 1.1 elric free(s); 437 1.1 elric free(i); 438 1.1 elric return 0; 439 1.1 elric } 440 1.1 elric 441 1.1 elric /** 442 1.1 elric * Add a certificate to the certificiate store. 443 1.1 elric * 444 1.1 elric * The receiving keyset certs will either increase reference counter 445 1.1 elric * of the cert or make a deep copy, either way, the caller needs to 446 1.1 elric * free the cert itself. 447 1.1 elric * 448 1.1 elric * @param context a hx509 context. 449 1.1 elric * @param certs certificate store to add the certificate to. 450 1.1 elric * @param cert certificate to add. 451 1.1 elric * 452 1.1 elric * @return Returns an hx509 error code. 453 1.1 elric * 454 1.1 elric * @ingroup hx509_keyset 455 1.1 elric */ 456 1.1 elric 457 1.1 elric int 458 1.1 elric hx509_certs_add(hx509_context context, hx509_certs certs, hx509_cert cert) 459 1.1 elric { 460 1.1 elric if (certs->ops->add == NULL) { 461 1.1 elric hx509_set_error_string(context, 0, ENOENT, 462 1.1 elric "Keyset type %s doesn't support add operation", 463 1.1 elric certs->ops->name); 464 1.1 elric return ENOENT; 465 1.1 elric } 466 1.1 elric 467 1.1 elric return (*certs->ops->add)(context, certs, certs->ops_data, cert); 468 1.1 elric } 469 1.1 elric 470 1.1 elric /** 471 1.1 elric * Find a certificate matching the query. 472 1.1 elric * 473 1.1 elric * @param context a hx509 context. 474 1.1 elric * @param certs certificate store to search. 475 1.1 elric * @param q query allocated with @ref hx509_query functions. 476 1.1 elric * @param r return certificate (or NULL on error), should be freed 477 1.1 elric * with hx509_cert_free(). 478 1.1 elric * 479 1.1 elric * @return Returns an hx509 error code. 480 1.1 elric * 481 1.1 elric * @ingroup hx509_keyset 482 1.1 elric */ 483 1.1 elric 484 1.1 elric int 485 1.1 elric hx509_certs_find(hx509_context context, 486 1.1 elric hx509_certs certs, 487 1.1 elric const hx509_query *q, 488 1.1 elric hx509_cert *r) 489 1.1 elric { 490 1.1 elric hx509_cursor cursor; 491 1.1 elric hx509_cert c; 492 1.1 elric int ret; 493 1.1 elric 494 1.1 elric *r = NULL; 495 1.1 elric 496 1.1 elric _hx509_query_statistic(context, 0, q); 497 1.1 elric 498 1.1 elric if (certs->ops->query) 499 1.1 elric return (*certs->ops->query)(context, certs, certs->ops_data, q, r); 500 1.1 elric 501 1.1 elric ret = hx509_certs_start_seq(context, certs, &cursor); 502 1.1 elric if (ret) 503 1.1 elric return ret; 504 1.1 elric 505 1.1 elric c = NULL; 506 1.1 elric while (1) { 507 1.1 elric ret = hx509_certs_next_cert(context, certs, cursor, &c); 508 1.1 elric if (ret) 509 1.1 elric break; 510 1.1 elric if (c == NULL) 511 1.1 elric break; 512 1.1 elric if (_hx509_query_match_cert(context, q, c)) { 513 1.1 elric *r = c; 514 1.1 elric break; 515 1.1 elric } 516 1.1 elric hx509_cert_free(c); 517 1.1 elric } 518 1.1 elric 519 1.1 elric hx509_certs_end_seq(context, certs, cursor); 520 1.1 elric if (ret) 521 1.1 elric return ret; 522 1.1 elric /** 523 1.1 elric * Return HX509_CERT_NOT_FOUND if no certificate in certs matched 524 1.1 elric * the query. 525 1.1 elric */ 526 1.1 elric if (c == NULL) { 527 1.1 elric hx509_clear_error_string(context); 528 1.1 elric return HX509_CERT_NOT_FOUND; 529 1.1 elric } 530 1.1 elric 531 1.1 elric return 0; 532 1.1 elric } 533 1.1 elric 534 1.1 elric /** 535 1.1 elric * Filter certificate matching the query. 536 1.1 elric * 537 1.1 elric * @param context a hx509 context. 538 1.1 elric * @param certs certificate store to search. 539 1.1 elric * @param q query allocated with @ref hx509_query functions. 540 1.1 elric * @param result the filtered certificate store, caller must free with 541 1.1 elric * hx509_certs_free(). 542 1.1 elric * 543 1.1 elric * @return Returns an hx509 error code. 544 1.1 elric * 545 1.1 elric * @ingroup hx509_keyset 546 1.1 elric */ 547 1.1 elric 548 1.1 elric int 549 1.1 elric hx509_certs_filter(hx509_context context, 550 1.1 elric hx509_certs certs, 551 1.1 elric const hx509_query *q, 552 1.1 elric hx509_certs *result) 553 1.1 elric { 554 1.1 elric hx509_cursor cursor; 555 1.1 elric hx509_cert c; 556 1.1 elric int ret, found = 0; 557 1.1 elric 558 1.1 elric _hx509_query_statistic(context, 0, q); 559 1.1 elric 560 1.1 elric ret = hx509_certs_init(context, "MEMORY:filter-certs", 0, 561 1.1 elric NULL, result); 562 1.1 elric if (ret) 563 1.1 elric return ret; 564 1.1 elric 565 1.1 elric ret = hx509_certs_start_seq(context, certs, &cursor); 566 1.1 elric if (ret) { 567 1.1 elric hx509_certs_free(result); 568 1.1 elric return ret; 569 1.1 elric } 570 1.1 elric 571 1.1 elric c = NULL; 572 1.1 elric while (1) { 573 1.1 elric ret = hx509_certs_next_cert(context, certs, cursor, &c); 574 1.1 elric if (ret) 575 1.1 elric break; 576 1.1 elric if (c == NULL) 577 1.1 elric break; 578 1.1 elric if (_hx509_query_match_cert(context, q, c)) { 579 1.1 elric hx509_certs_add(context, *result, c); 580 1.1 elric found = 1; 581 1.1 elric } 582 1.1 elric hx509_cert_free(c); 583 1.1 elric } 584 1.1 elric 585 1.1 elric hx509_certs_end_seq(context, certs, cursor); 586 1.1 elric if (ret) { 587 1.1 elric hx509_certs_free(result); 588 1.1 elric return ret; 589 1.1 elric } 590 1.1 elric 591 1.1 elric /** 592 1.1 elric * Return HX509_CERT_NOT_FOUND if no certificate in certs matched 593 1.1 elric * the query. 594 1.1 elric */ 595 1.1 elric if (!found) { 596 1.1 elric hx509_certs_free(result); 597 1.1 elric hx509_clear_error_string(context); 598 1.1 elric return HX509_CERT_NOT_FOUND; 599 1.1 elric } 600 1.1 elric 601 1.1 elric return 0; 602 1.1 elric } 603 1.1 elric 604 1.1 elric 605 1.1 elric static int 606 1.1 elric certs_merge_func(hx509_context context, void *ctx, hx509_cert c) 607 1.1 elric { 608 1.1 elric return hx509_certs_add(context, (hx509_certs)ctx, c); 609 1.1 elric } 610 1.1 elric 611 1.1 elric /** 612 1.1 elric * Merge a certificate store into another. The from store is keep 613 1.1 elric * intact. 614 1.1 elric * 615 1.1 elric * @param context a hx509 context. 616 1.1 elric * @param to the store to merge into. 617 1.1 elric * @param from the store to copy the object from. 618 1.1 elric * 619 1.1 elric * @return Returns an hx509 error code. 620 1.1 elric * 621 1.1 elric * @ingroup hx509_keyset 622 1.1 elric */ 623 1.1 elric 624 1.1 elric int 625 1.1 elric hx509_certs_merge(hx509_context context, hx509_certs to, hx509_certs from) 626 1.1 elric { 627 1.1 elric if (from == NULL) 628 1.1 elric return 0; 629 1.1 elric return hx509_certs_iter_f(context, from, certs_merge_func, to); 630 1.1 elric } 631 1.1 elric 632 1.1 elric /** 633 1.1 elric * Same a hx509_certs_merge() but use a lock and name to describe the 634 1.1 elric * from source. 635 1.1 elric * 636 1.1 elric * @param context a hx509 context. 637 1.1 elric * @param to the store to merge into. 638 1.1 elric * @param lock a lock that unlocks the certificates store, use NULL to 639 1.1 elric * select no password/certifictes/prompt lock (see @ref page_lock). 640 1.1 elric * @param name name of the source store 641 1.1 elric * 642 1.1 elric * @return Returns an hx509 error code. 643 1.1 elric * 644 1.1 elric * @ingroup hx509_keyset 645 1.1 elric */ 646 1.1 elric 647 1.1 elric int 648 1.1 elric hx509_certs_append(hx509_context context, 649 1.1 elric hx509_certs to, 650 1.1 elric hx509_lock lock, 651 1.1 elric const char *name) 652 1.1 elric { 653 1.1 elric hx509_certs s; 654 1.1 elric int ret; 655 1.1 elric 656 1.1 elric ret = hx509_certs_init(context, name, 0, lock, &s); 657 1.1 elric if (ret) 658 1.1 elric return ret; 659 1.1 elric ret = hx509_certs_merge(context, to, s); 660 1.1 elric hx509_certs_free(&s); 661 1.1 elric return ret; 662 1.1 elric } 663 1.1 elric 664 1.1 elric /** 665 1.1 elric * Get one random certificate from the certificate store. 666 1.1 elric * 667 1.1 elric * @param context a hx509 context. 668 1.1 elric * @param certs a certificate store to get the certificate from. 669 1.1 elric * @param c return certificate, should be freed with hx509_cert_free(). 670 1.1 elric * 671 1.1 elric * @return Returns an hx509 error code. 672 1.1 elric * 673 1.1 elric * @ingroup hx509_keyset 674 1.1 elric */ 675 1.1 elric 676 1.1 elric int 677 1.1 elric hx509_get_one_cert(hx509_context context, hx509_certs certs, hx509_cert *c) 678 1.1 elric { 679 1.1 elric hx509_cursor cursor; 680 1.1 elric int ret; 681 1.1 elric 682 1.1 elric *c = NULL; 683 1.1 elric 684 1.1 elric ret = hx509_certs_start_seq(context, certs, &cursor); 685 1.1 elric if (ret) 686 1.1 elric return ret; 687 1.1 elric 688 1.1 elric ret = hx509_certs_next_cert(context, certs, cursor, c); 689 1.1 elric if (ret) 690 1.1 elric return ret; 691 1.1 elric 692 1.1 elric hx509_certs_end_seq(context, certs, cursor); 693 1.1 elric return 0; 694 1.1 elric } 695 1.1 elric 696 1.1 elric static int 697 1.1 elric certs_info_stdio(void *ctx, const char *str) 698 1.1 elric { 699 1.1 elric FILE *f = ctx; 700 1.1 elric fprintf(f, "%s\n", str); 701 1.1 elric return 0; 702 1.1 elric } 703 1.1 elric 704 1.1 elric /** 705 1.1 elric * Print some info about the certificate store. 706 1.1 elric * 707 1.1 elric * @param context a hx509 context. 708 1.1 elric * @param certs certificate store to print information about. 709 1.1 elric * @param func function that will get each line of the information, if 710 1.1 elric * NULL is used the data is printed on a FILE descriptor that should 711 1.1 elric * be passed in ctx, if ctx also is NULL, stdout is used. 712 1.1 elric * @param ctx parameter to func. 713 1.1 elric * 714 1.1 elric * @return Returns an hx509 error code. 715 1.1 elric * 716 1.1 elric * @ingroup hx509_keyset 717 1.1 elric */ 718 1.1 elric 719 1.1 elric int 720 1.1 elric hx509_certs_info(hx509_context context, 721 1.1 elric hx509_certs certs, 722 1.1 elric int (*func)(void *, const char *), 723 1.1 elric void *ctx) 724 1.1 elric { 725 1.1 elric if (func == NULL) { 726 1.1 elric func = certs_info_stdio; 727 1.1 elric if (ctx == NULL) 728 1.1 elric ctx = stdout; 729 1.1 elric } 730 1.1 elric if (certs->ops->printinfo == NULL) { 731 1.1 elric (*func)(ctx, "No info function for certs"); 732 1.1 elric return 0; 733 1.1 elric } 734 1.1 elric return (*certs->ops->printinfo)(context, certs, certs->ops_data, 735 1.1 elric func, ctx); 736 1.1 elric } 737 1.1 elric 738 1.1 elric void 739 1.1 elric _hx509_pi_printf(int (*func)(void *, const char *), void *ctx, 740 1.1 elric const char *fmt, ...) 741 1.1 elric { 742 1.1 elric va_list ap; 743 1.1 elric char *str; 744 1.2 christos int ret; 745 1.1 elric 746 1.1 elric va_start(ap, fmt); 747 1.2 christos ret = vasprintf(&str, fmt, ap); 748 1.1 elric va_end(ap); 749 1.2 christos if (ret == -1 || str == NULL) 750 1.1 elric return; 751 1.1 elric (*func)(ctx, str); 752 1.1 elric free(str); 753 1.1 elric } 754 1.1 elric 755 1.1 elric int 756 1.1 elric _hx509_certs_keys_get(hx509_context context, 757 1.1 elric hx509_certs certs, 758 1.1 elric hx509_private_key **keys) 759 1.1 elric { 760 1.1 elric if (certs->ops->getkeys == NULL) { 761 1.1 elric *keys = NULL; 762 1.1 elric return 0; 763 1.1 elric } 764 1.1 elric return (*certs->ops->getkeys)(context, certs, certs->ops_data, keys); 765 1.1 elric } 766 1.1 elric 767 1.1 elric int 768 1.1 elric _hx509_certs_keys_add(hx509_context context, 769 1.1 elric hx509_certs certs, 770 1.1 elric hx509_private_key key) 771 1.1 elric { 772 1.1 elric if (certs->ops->addkey == NULL) { 773 1.1 elric hx509_set_error_string(context, 0, EINVAL, 774 1.1 elric "keystore if type %s doesn't support " 775 1.1 elric "key add operation", 776 1.1 elric certs->ops->name); 777 1.1 elric return EINVAL; 778 1.1 elric } 779 1.1 elric return (*certs->ops->addkey)(context, certs, certs->ops_data, key); 780 1.1 elric } 781 1.1 elric 782 1.1 elric 783 1.1 elric void 784 1.1 elric _hx509_certs_keys_free(hx509_context context, 785 1.1 elric hx509_private_key *keys) 786 1.1 elric { 787 1.1 elric int i; 788 1.1 elric for (i = 0; keys[i]; i++) 789 1.1 elric hx509_private_key_free(&keys[i]); 790 1.1 elric free(keys); 791 1.1 elric } 792