/src/openssl30/crypto/store/store_lib.c
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | /* | 
| 2 |  |  * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. | 
| 3 |  |  * | 
| 4 |  |  * Licensed under the Apache License 2.0 (the "License").  You may not use | 
| 5 |  |  * this file except in compliance with the License.  You can obtain a copy | 
| 6 |  |  * in the file LICENSE in the source distribution or at | 
| 7 |  |  * https://www.openssl.org/source/license.html | 
| 8 |  |  */ | 
| 9 |  |  | 
| 10 |  | #include <stdlib.h> | 
| 11 |  | #include <string.h> | 
| 12 |  | #include <assert.h> | 
| 13 |  |  | 
| 14 |  | /* We need to use some STORE deprecated APIs */ | 
| 15 |  | #define OPENSSL_SUPPRESS_DEPRECATED | 
| 16 |  |  | 
| 17 |  | #include "e_os.h" | 
| 18 |  |  | 
| 19 |  | #include <openssl/crypto.h> | 
| 20 |  | #include <openssl/err.h> | 
| 21 |  | #include <openssl/trace.h> | 
| 22 |  | #include <openssl/core_names.h> | 
| 23 |  | #include <openssl/provider.h> | 
| 24 |  | #include <openssl/param_build.h> | 
| 25 |  | #include <openssl/store.h> | 
| 26 |  | #include "internal/thread_once.h" | 
| 27 |  | #include "internal/cryptlib.h" | 
| 28 |  | #include "internal/provider.h" | 
| 29 |  | #include "internal/bio.h" | 
| 30 |  | #include "crypto/store.h" | 
| 31 |  | #include "store_local.h" | 
| 32 |  |  | 
| 33 |  | static int ossl_store_close_it(OSSL_STORE_CTX *ctx); | 
| 34 |  |  | 
| 35 |  | static int loader_set_params(OSSL_STORE_LOADER *loader, | 
| 36 |  |                              OSSL_STORE_LOADER_CTX *loader_ctx, | 
| 37 |  |                              const OSSL_PARAM params[], const char *propq) | 
| 38 | 0 | { | 
| 39 | 0 |    if (params != NULL) { | 
| 40 | 0 |        if (!loader->p_set_ctx_params(loader_ctx, params)) | 
| 41 | 0 |            return 0; | 
| 42 | 0 |    } | 
| 43 |  |  | 
| 44 | 0 |    if (propq != NULL) { | 
| 45 | 0 |        OSSL_PARAM propp[2]; | 
| 46 |  | 
 | 
| 47 | 0 |        if (OSSL_PARAM_locate_const(params, | 
| 48 | 0 |                                    OSSL_STORE_PARAM_PROPERTIES) != NULL) | 
| 49 |  |            /* use the propq from params */ | 
| 50 | 0 |            return 1; | 
| 51 |  |  | 
| 52 | 0 |        propp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_PROPERTIES, | 
| 53 | 0 |                                                    (char *)propq, 0); | 
| 54 | 0 |        propp[1] = OSSL_PARAM_construct_end(); | 
| 55 |  | 
 | 
| 56 | 0 |        if (!loader->p_set_ctx_params(loader_ctx, propp)) | 
| 57 | 0 |            return 0; | 
| 58 | 0 |     } | 
| 59 | 0 |     return 1; | 
| 60 | 0 | } | 
| 61 |  |  | 
| 62 |  | OSSL_STORE_CTX * | 
| 63 |  | OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, | 
| 64 |  |                    const UI_METHOD *ui_method, void *ui_data, | 
| 65 |  |                    const OSSL_PARAM params[], | 
| 66 |  |                    OSSL_STORE_post_process_info_fn post_process, | 
| 67 |  |                    void *post_process_data) | 
| 68 | 0 | { | 
| 69 | 0 |     const OSSL_STORE_LOADER *loader = NULL; | 
| 70 | 0 |     OSSL_STORE_LOADER *fetched_loader = NULL; | 
| 71 | 0 |     OSSL_STORE_LOADER_CTX *loader_ctx = NULL; | 
| 72 | 0 |     OSSL_STORE_CTX *ctx = NULL; | 
| 73 | 0 |     char *propq_copy = NULL; | 
| 74 | 0 |     int no_loader_found = 1; | 
| 75 | 0 |     char scheme_copy[256], *p, *schemes[2], *scheme = NULL; | 
| 76 | 0 |     size_t schemes_n = 0; | 
| 77 | 0 |     size_t i; | 
| 78 |  |  | 
| 79 |  |     /* | 
| 80 |  |      * Put the file scheme first.  If the uri does represent an existing file, | 
| 81 |  |      * possible device name and all, then it should be loaded.  Only a failed | 
| 82 |  |      * attempt at loading a local file should have us try something else. | 
| 83 |  |      */ | 
| 84 | 0 |     schemes[schemes_n++] = "file"; | 
| 85 |  |  | 
| 86 |  |     /* | 
| 87 |  |      * Now, check if we have something that looks like a scheme, and add it | 
| 88 |  |      * as a second scheme.  However, also check if there's an authority start | 
| 89 |  |      * (://), because that will invalidate the previous file scheme.  Also, | 
| 90 |  |      * check that this isn't actually the file scheme, as there's no point | 
| 91 |  |      * going through that one twice! | 
| 92 |  |      */ | 
| 93 | 0 |     OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy)); | 
| 94 | 0 |     if ((p = strchr(scheme_copy, ':')) != NULL) { | 
| 95 | 0 |         *p++ = '\0'; | 
| 96 | 0 |         if (OPENSSL_strcasecmp(scheme_copy, "file") != 0) { | 
| 97 | 0 |             if (strncmp(p, "//", 2) == 0) | 
| 98 | 0 |                 schemes_n--;         /* Invalidate the file scheme */ | 
| 99 | 0 |             schemes[schemes_n++] = scheme_copy; | 
| 100 | 0 |         } | 
| 101 | 0 |     } | 
| 102 |  | 
 | 
| 103 | 0 |     ERR_set_mark(); | 
| 104 |  |  | 
| 105 |  |     /* | 
| 106 |  |      * Try each scheme until we find one that could open the URI. | 
| 107 |  |      * | 
| 108 |  |      * For each scheme, we look for the engine implementation first, and | 
| 109 |  |      * failing that, we then try to fetch a provided implementation. | 
| 110 |  |      * This is consistent with how we handle legacy / engine implementations | 
| 111 |  |      * elsewhere. | 
| 112 |  |      */ | 
| 113 | 0 |     for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { | 
| 114 | 0 |         scheme = schemes[i]; | 
| 115 | 0 |         OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); | 
| 116 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 117 | 0 |         if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) { | 
| 118 | 0 |             no_loader_found = 0; | 
| 119 | 0 |             if (loader->open_ex != NULL) | 
| 120 | 0 |                 loader_ctx = loader->open_ex(loader, uri, libctx, propq, | 
| 121 | 0 |                                              ui_method, ui_data); | 
| 122 | 0 |             else | 
| 123 | 0 |                 loader_ctx = loader->open(loader, uri, ui_method, ui_data); | 
| 124 | 0 |         } | 
| 125 | 0 | #endif | 
| 126 | 0 |         if (loader == NULL | 
| 127 | 0 |             && (fetched_loader = | 
| 128 | 0 |                 OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) { | 
| 129 | 0 |             const OSSL_PROVIDER *provider = | 
| 130 | 0 |                 OSSL_STORE_LOADER_get0_provider(fetched_loader); | 
| 131 | 0 |             void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); | 
| 132 |  | 
 | 
| 133 | 0 |             no_loader_found = 0; | 
| 134 | 0 |             loader_ctx = fetched_loader->p_open(provctx, uri); | 
| 135 | 0 |             if (loader_ctx == NULL) { | 
| 136 | 0 |                 OSSL_STORE_LOADER_free(fetched_loader); | 
| 137 | 0 |                 fetched_loader = NULL; | 
| 138 | 0 |             } else if(!loader_set_params(fetched_loader, loader_ctx, | 
| 139 | 0 |                                          params, propq)) { | 
| 140 | 0 |                 (void)fetched_loader->p_close(loader_ctx); | 
| 141 | 0 |                 OSSL_STORE_LOADER_free(fetched_loader); | 
| 142 | 0 |                 fetched_loader = NULL; | 
| 143 | 0 |             } | 
| 144 | 0 |             loader = fetched_loader; | 
| 145 | 0 |         } | 
| 146 | 0 |     } | 
| 147 |  | 
 | 
| 148 | 0 |     if (no_loader_found) | 
| 149 |  |         /* | 
| 150 |  |          * It's assumed that ossl_store_get0_loader_int() and | 
| 151 |  |          * OSSL_STORE_LOADER_fetch() report their own errors | 
| 152 |  |          */ | 
| 153 | 0 |         goto err; | 
| 154 |  |  | 
| 155 | 0 |     OSSL_TRACE1(STORE, "Found loader for scheme %s\n", scheme); | 
| 156 |  | 
 | 
| 157 | 0 |     if (loader_ctx == NULL) | 
| 158 |  |         /* | 
| 159 |  |          * It's assumed that the loader's open() method reports its own | 
| 160 |  |          * errors | 
| 161 |  |          */ | 
| 162 | 0 |         goto err; | 
| 163 |  |  | 
| 164 | 0 |     OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); | 
| 165 |  | 
 | 
| 166 | 0 |     if ((propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL) | 
| 167 | 0 |         || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { | 
| 168 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 169 | 0 |         goto err; | 
| 170 | 0 |     } | 
| 171 |  |  | 
| 172 | 0 |     if (ui_method != NULL | 
| 173 | 0 |         && (!ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data) | 
| 174 | 0 |             || !ossl_pw_enable_passphrase_caching(&ctx->pwdata))) { | 
| 175 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); | 
| 176 | 0 |         goto err; | 
| 177 | 0 |     } | 
| 178 | 0 |     ctx->properties = propq_copy; | 
| 179 | 0 |     ctx->fetched_loader = fetched_loader; | 
| 180 | 0 |     ctx->loader = loader; | 
| 181 | 0 |     ctx->loader_ctx = loader_ctx; | 
| 182 | 0 |     ctx->post_process = post_process; | 
| 183 | 0 |     ctx->post_process_data = post_process_data; | 
| 184 |  |  | 
| 185 |  |     /* | 
| 186 |  |      * If the attempt to open with the 'file' scheme loader failed and the | 
| 187 |  |      * other scheme loader succeeded, the failure to open with the 'file' | 
| 188 |  |      * scheme loader leaves an error on the error stack.  Let's remove it. | 
| 189 |  |      */ | 
| 190 | 0 |     ERR_pop_to_mark(); | 
| 191 |  | 
 | 
| 192 | 0 |     return ctx; | 
| 193 |  |  | 
| 194 | 0 |  err: | 
| 195 | 0 |     ERR_clear_last_mark(); | 
| 196 | 0 |     if (loader_ctx != NULL) { | 
| 197 |  |         /* | 
| 198 |  |          * Temporary structure so OSSL_STORE_close() can work even when | 
| 199 |  |          * |ctx| couldn't be allocated properly | 
| 200 |  |          */ | 
| 201 | 0 |         OSSL_STORE_CTX tmpctx = { NULL, }; | 
| 202 |  | 
 | 
| 203 | 0 |         tmpctx.fetched_loader = fetched_loader; | 
| 204 | 0 |         tmpctx.loader = loader; | 
| 205 | 0 |         tmpctx.loader_ctx = loader_ctx; | 
| 206 |  |  | 
| 207 |  |         /* | 
| 208 |  |          * We ignore a returned error because we will return NULL anyway in | 
| 209 |  |          * this case, so if something goes wrong when closing, that'll simply | 
| 210 |  |          * just add another entry on the error stack. | 
| 211 |  |          */ | 
| 212 | 0 |         (void)ossl_store_close_it(&tmpctx); | 
| 213 | 0 |     } | 
| 214 | 0 |     OSSL_STORE_LOADER_free(fetched_loader); | 
| 215 | 0 |     OPENSSL_free(propq_copy); | 
| 216 | 0 |     OPENSSL_free(ctx); | 
| 217 | 0 |     return NULL; | 
| 218 | 0 | } | 
| 219 |  |  | 
| 220 |  | OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, | 
| 221 |  |                                 const UI_METHOD *ui_method, void *ui_data, | 
| 222 |  |                                 OSSL_STORE_post_process_info_fn post_process, | 
| 223 |  |                                 void *post_process_data) | 
| 224 | 0 | { | 
| 225 | 0 |     return OSSL_STORE_open_ex(uri, NULL, NULL, ui_method, ui_data, NULL, | 
| 226 | 0 |                               post_process, post_process_data); | 
| 227 | 0 | } | 
| 228 |  |  | 
| 229 |  | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 230 |  | int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) | 
| 231 | 0 | { | 
| 232 | 0 |     va_list args; | 
| 233 | 0 |     int ret; | 
| 234 |  | 
 | 
| 235 | 0 |     va_start(args, cmd); | 
| 236 | 0 |     ret = OSSL_STORE_vctrl(ctx, cmd, args); | 
| 237 | 0 |     va_end(args); | 
| 238 |  | 
 | 
| 239 | 0 |     return ret; | 
| 240 | 0 | } | 
| 241 |  |  | 
| 242 |  | int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args) | 
| 243 | 0 | { | 
| 244 | 0 |     if (ctx->fetched_loader != NULL) { | 
| 245 | 0 |         if (ctx->fetched_loader->p_set_ctx_params != NULL) { | 
| 246 | 0 |             OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | 
| 247 |  | 
 | 
| 248 | 0 |             switch (cmd) { | 
| 249 | 0 |             case OSSL_STORE_C_USE_SECMEM: | 
| 250 | 0 |                 { | 
| 251 | 0 |                     int on = *(va_arg(args, int *)); | 
| 252 |  | 
 | 
| 253 | 0 |                     params[0] = OSSL_PARAM_construct_int("use_secmem", &on); | 
| 254 | 0 |                 } | 
| 255 | 0 |                 break; | 
| 256 | 0 |             default: | 
| 257 | 0 |                 break; | 
| 258 | 0 |             } | 
| 259 |  |  | 
| 260 | 0 |             return ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, | 
| 261 | 0 |                                                          params); | 
| 262 | 0 |         } | 
| 263 | 0 |     } else if (ctx->loader->ctrl != NULL) { | 
| 264 | 0 |         return ctx->loader->ctrl(ctx->loader_ctx, cmd, args); | 
| 265 | 0 |     } | 
| 266 |  |  | 
| 267 |  |     /* | 
| 268 |  |      * If the fetched loader doesn't have a set_ctx_params or a ctrl, it's as | 
| 269 |  |      * if there was one that ignored our params, which usually returns 1. | 
| 270 |  |      */ | 
| 271 | 0 |     return 1; | 
| 272 | 0 | } | 
| 273 |  | #endif | 
| 274 |  |  | 
| 275 |  | int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) | 
| 276 | 0 | { | 
| 277 | 0 |     int ret = 1; | 
| 278 |  | 
 | 
| 279 | 0 |     if (ctx == NULL | 
| 280 | 0 |             || expected_type < 0 || expected_type > OSSL_STORE_INFO_CRL) { | 
| 281 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); | 
| 282 | 0 |         return 0; | 
| 283 | 0 |     } | 
| 284 | 0 |     if (ctx->loading) { | 
| 285 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); | 
| 286 | 0 |         return 0; | 
| 287 | 0 |     } | 
| 288 |  |  | 
| 289 | 0 |     ctx->expected_type = expected_type; | 
| 290 | 0 |     if (ctx->fetched_loader != NULL | 
| 291 | 0 |         && ctx->fetched_loader->p_set_ctx_params != NULL) { | 
| 292 | 0 |         OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | 
| 293 |  | 
 | 
| 294 | 0 |         params[0] = | 
| 295 | 0 |             OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expected_type); | 
| 296 | 0 |         ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, params); | 
| 297 | 0 |     } | 
| 298 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 299 | 0 |     if (ctx->fetched_loader == NULL | 
| 300 | 0 |         && ctx->loader->expect != NULL) { | 
| 301 | 0 |         ret = ctx->loader->expect(ctx->loader_ctx, expected_type); | 
| 302 | 0 |     } | 
| 303 | 0 | #endif | 
| 304 | 0 |     return ret; | 
| 305 | 0 | } | 
| 306 |  |  | 
| 307 |  | int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) | 
| 308 | 0 | { | 
| 309 | 0 |     int ret = 1; | 
| 310 |  | 
 | 
| 311 | 0 |     if (ctx->loading) { | 
| 312 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); | 
| 313 | 0 |         return 0; | 
| 314 | 0 |     } | 
| 315 | 0 |     if (search == NULL) { | 
| 316 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); | 
| 317 | 0 |         return 0; | 
| 318 | 0 |     } | 
| 319 |  |  | 
| 320 | 0 |     if (ctx->fetched_loader != NULL) { | 
| 321 | 0 |         OSSL_PARAM_BLD *bld; | 
| 322 | 0 |         OSSL_PARAM *params; | 
| 323 |  |         /* OSSL_STORE_SEARCH_BY_NAME, OSSL_STORE_SEARCH_BY_ISSUER_SERIAL*/ | 
| 324 | 0 |         void *name_der = NULL; | 
| 325 | 0 |         int name_der_sz; | 
| 326 |  |         /* OSSL_STORE_SEARCH_BY_ISSUER_SERIAL */ | 
| 327 | 0 |         BIGNUM *number = NULL; | 
| 328 |  | 
 | 
| 329 | 0 |         if (ctx->fetched_loader->p_set_ctx_params == NULL) { | 
| 330 | 0 |             ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); | 
| 331 | 0 |             return 0; | 
| 332 | 0 |         } | 
| 333 |  |  | 
| 334 | 0 |         if ((bld = OSSL_PARAM_BLD_new()) == NULL) { | 
| 335 | 0 |             ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 336 | 0 |             return 0; | 
| 337 | 0 |         } | 
| 338 |  |  | 
| 339 | 0 |         ret = 0;                 /* Assume the worst */ | 
| 340 |  | 
 | 
| 341 | 0 |         switch (search->search_type) { | 
| 342 | 0 |         case OSSL_STORE_SEARCH_BY_NAME: | 
| 343 | 0 |             if ((name_der_sz = i2d_X509_NAME(search->name, | 
| 344 | 0 |                                              (unsigned char **)&name_der)) > 0 | 
| 345 | 0 |                 && OSSL_PARAM_BLD_push_octet_string(bld, | 
| 346 | 0 |                                                     OSSL_STORE_PARAM_SUBJECT, | 
| 347 | 0 |                                                     name_der, name_der_sz)) | 
| 348 | 0 |                 ret = 1; | 
| 349 | 0 |             break; | 
| 350 | 0 |         case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: | 
| 351 | 0 |             if ((name_der_sz = i2d_X509_NAME(search->name, | 
| 352 | 0 |                                              (unsigned char **)&name_der)) > 0 | 
| 353 | 0 |                 && (number = ASN1_INTEGER_to_BN(search->serial, NULL)) != NULL | 
| 354 | 0 |                 && OSSL_PARAM_BLD_push_octet_string(bld, | 
| 355 | 0 |                                                     OSSL_STORE_PARAM_ISSUER, | 
| 356 | 0 |                                                     name_der, name_der_sz) | 
| 357 | 0 |                 && OSSL_PARAM_BLD_push_BN(bld, OSSL_STORE_PARAM_SERIAL, | 
| 358 | 0 |                                           number)) | 
| 359 | 0 |                 ret = 1; | 
| 360 | 0 |             break; | 
| 361 | 0 |         case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: | 
| 362 | 0 |             if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_DIGEST, | 
| 363 | 0 |                                                 EVP_MD_get0_name(search->digest), | 
| 364 | 0 |                                                 0) | 
| 365 | 0 |                 && OSSL_PARAM_BLD_push_octet_string(bld, | 
| 366 | 0 |                                                     OSSL_STORE_PARAM_FINGERPRINT, | 
| 367 | 0 |                                                     search->string, | 
| 368 | 0 |                                                     search->stringlength)) | 
| 369 | 0 |                 ret = 1; | 
| 370 | 0 |             break; | 
| 371 | 0 |         case OSSL_STORE_SEARCH_BY_ALIAS: | 
| 372 | 0 |             if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_ALIAS, | 
| 373 | 0 |                                                 (char *)search->string, | 
| 374 | 0 |                                                 search->stringlength)) | 
| 375 | 0 |                 ret = 1; | 
| 376 | 0 |             break; | 
| 377 | 0 |         } | 
| 378 | 0 |         if (ret) { | 
| 379 | 0 |             params = OSSL_PARAM_BLD_to_param(bld); | 
| 380 | 0 |             ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, | 
| 381 | 0 |                                                         params); | 
| 382 | 0 |             OSSL_PARAM_free(params); | 
| 383 | 0 |         } | 
| 384 | 0 |         OSSL_PARAM_BLD_free(bld); | 
| 385 | 0 |         OPENSSL_free(name_der); | 
| 386 | 0 |         BN_free(number); | 
| 387 | 0 |     } else { | 
| 388 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 389 |  |         /* legacy loader section */ | 
| 390 | 0 |         if (ctx->loader->find == NULL) { | 
| 391 | 0 |             ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); | 
| 392 | 0 |             return 0; | 
| 393 | 0 |         } | 
| 394 | 0 |         ret = ctx->loader->find(ctx->loader_ctx, search); | 
| 395 | 0 | #endif | 
| 396 | 0 |     } | 
| 397 |  |  | 
| 398 | 0 |     return ret; | 
| 399 | 0 | } | 
| 400 |  |  | 
| 401 |  | OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) | 
| 402 | 0 | { | 
| 403 | 0 |     OSSL_STORE_INFO *v = NULL; | 
| 404 |  | 
 | 
| 405 | 0 |     ctx->loading = 1; | 
| 406 | 0 |  again: | 
| 407 | 0 |     if (OSSL_STORE_eof(ctx)) | 
| 408 | 0 |         return NULL; | 
| 409 |  |  | 
| 410 | 0 |     if (ctx->loader != NULL) | 
| 411 | 0 |         OSSL_TRACE(STORE, "Loading next object\n"); | 
| 412 |  | 
 | 
| 413 | 0 |     if (ctx->cached_info != NULL | 
| 414 | 0 |         && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) { | 
| 415 | 0 |         sk_OSSL_STORE_INFO_free(ctx->cached_info); | 
| 416 | 0 |         ctx->cached_info = NULL; | 
| 417 | 0 |     } | 
| 418 |  | 
 | 
| 419 | 0 |     if (ctx->cached_info != NULL) { | 
| 420 | 0 |         v = sk_OSSL_STORE_INFO_shift(ctx->cached_info); | 
| 421 | 0 |     } else { | 
| 422 | 0 |         if (ctx->fetched_loader != NULL) { | 
| 423 | 0 |             struct ossl_load_result_data_st load_data; | 
| 424 |  | 
 | 
| 425 | 0 |             load_data.v = NULL; | 
| 426 | 0 |             load_data.ctx = ctx; | 
| 427 | 0 |             ctx->error_flag = 0; | 
| 428 |  | 
 | 
| 429 | 0 |             if (!ctx->fetched_loader->p_load(ctx->loader_ctx, | 
| 430 | 0 |                                              ossl_store_handle_load_result, | 
| 431 | 0 |                                              &load_data, | 
| 432 | 0 |                                              ossl_pw_passphrase_callback_dec, | 
| 433 | 0 |                                              &ctx->pwdata)) { | 
| 434 | 0 |                 ctx->error_flag = 1; | 
| 435 | 0 |                 return NULL; | 
| 436 | 0 |             } | 
| 437 | 0 |             v = load_data.v; | 
| 438 | 0 |         } | 
| 439 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 440 | 0 |         if (ctx->fetched_loader == NULL) | 
| 441 | 0 |             v = ctx->loader->load(ctx->loader_ctx, | 
| 442 | 0 |                                   ctx->pwdata._.ui_method.ui_method, | 
| 443 | 0 |                                   ctx->pwdata._.ui_method.ui_method_data); | 
| 444 | 0 | #endif | 
| 445 | 0 |     } | 
| 446 |  |  | 
| 447 | 0 |     if (ctx->post_process != NULL && v != NULL) { | 
| 448 | 0 |         v = ctx->post_process(v, ctx->post_process_data); | 
| 449 |  |  | 
| 450 |  |         /* | 
| 451 |  |          * By returning NULL, the callback decides that this object should | 
| 452 |  |          * be ignored. | 
| 453 |  |          */ | 
| 454 | 0 |         if (v == NULL) | 
| 455 | 0 |             goto again; | 
| 456 | 0 |     } | 
| 457 |  |  | 
| 458 |  |     /* Clear any internally cached passphrase */ | 
| 459 | 0 |     (void)ossl_pw_clear_passphrase_cache(&ctx->pwdata); | 
| 460 |  | 
 | 
| 461 | 0 |     if (v != NULL && ctx->expected_type != 0) { | 
| 462 | 0 |         int returned_type = OSSL_STORE_INFO_get_type(v); | 
| 463 |  | 
 | 
| 464 | 0 |         if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) { | 
| 465 | 0 |             if (ctx->expected_type != returned_type) { | 
| 466 | 0 |                 OSSL_STORE_INFO_free(v); | 
| 467 | 0 |                 goto again; | 
| 468 | 0 |             } | 
| 469 | 0 |         } | 
| 470 | 0 |     } | 
| 471 |  |  | 
| 472 | 0 |     if (v != NULL) | 
| 473 | 0 |         OSSL_TRACE1(STORE, "Got a %s\n", | 
| 474 | 0 |                     OSSL_STORE_INFO_type_string(OSSL_STORE_INFO_get_type(v))); | 
| 475 |  | 
 | 
| 476 | 0 |     return v; | 
| 477 | 0 | } | 
| 478 |  |  | 
| 479 |  | int OSSL_STORE_error(OSSL_STORE_CTX *ctx) | 
| 480 | 0 | { | 
| 481 | 0 |     int ret = 1; | 
| 482 |  | 
 | 
| 483 | 0 |     if (ctx->fetched_loader != NULL) | 
| 484 | 0 |         ret = ctx->error_flag; | 
| 485 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 486 | 0 |     if (ctx->fetched_loader == NULL) | 
| 487 | 0 |         ret = ctx->loader->error(ctx->loader_ctx); | 
| 488 | 0 | #endif | 
| 489 | 0 |     return ret; | 
| 490 | 0 | } | 
| 491 |  |  | 
| 492 |  | int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) | 
| 493 | 0 | { | 
| 494 | 0 |     int ret = 1; | 
| 495 |  | 
 | 
| 496 | 0 |     if (ctx->fetched_loader != NULL) | 
| 497 | 0 |         ret = ctx->loader->p_eof(ctx->loader_ctx); | 
| 498 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 499 | 0 |     if (ctx->fetched_loader == NULL) | 
| 500 | 0 |         ret = ctx->loader->eof(ctx->loader_ctx); | 
| 501 | 0 | #endif | 
| 502 | 0 |     return ret != 0; | 
| 503 | 0 | } | 
| 504 |  |  | 
| 505 |  | static int ossl_store_close_it(OSSL_STORE_CTX *ctx) | 
| 506 | 0 | { | 
| 507 | 0 |     int ret = 0; | 
| 508 |  | 
 | 
| 509 | 0 |     if (ctx == NULL) | 
| 510 | 0 |         return 1; | 
| 511 | 0 |     OSSL_TRACE1(STORE, "Closing %p\n", (void *)ctx->loader_ctx); | 
| 512 |  | 
 | 
| 513 | 0 |     if (ctx->fetched_loader != NULL) | 
| 514 | 0 |         ret = ctx->loader->p_close(ctx->loader_ctx); | 
| 515 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 516 | 0 |     if (ctx->fetched_loader == NULL) | 
| 517 | 0 |         ret = ctx->loader->closefn(ctx->loader_ctx); | 
| 518 | 0 | #endif | 
| 519 |  | 
 | 
| 520 | 0 |     sk_OSSL_STORE_INFO_pop_free(ctx->cached_info, OSSL_STORE_INFO_free); | 
| 521 | 0 |     OSSL_STORE_LOADER_free(ctx->fetched_loader); | 
| 522 | 0 |     OPENSSL_free(ctx->properties); | 
| 523 | 0 |     ossl_pw_clear_passphrase_data(&ctx->pwdata); | 
| 524 | 0 |     return ret; | 
| 525 | 0 | } | 
| 526 |  |  | 
| 527 |  | int OSSL_STORE_close(OSSL_STORE_CTX *ctx) | 
| 528 | 0 | { | 
| 529 | 0 |     int ret = ossl_store_close_it(ctx); | 
| 530 |  | 
 | 
| 531 | 0 |     OPENSSL_free(ctx); | 
| 532 | 0 |     return ret; | 
| 533 | 0 | } | 
| 534 |  |  | 
| 535 |  | /* | 
| 536 |  |  * Functions to generate OSSL_STORE_INFOs, one function for each type we | 
| 537 |  |  * support having in them as well as a generic constructor. | 
| 538 |  |  * | 
| 539 |  |  * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO | 
| 540 |  |  * and will therefore be freed when the OSSL_STORE_INFO is freed. | 
| 541 |  |  */ | 
| 542 |  | OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data) | 
| 543 | 0 | { | 
| 544 | 0 |     OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info)); | 
| 545 |  | 
 | 
| 546 | 0 |     if (info == NULL) | 
| 547 | 0 |         return NULL; | 
| 548 |  |  | 
| 549 | 0 |     info->type = type; | 
| 550 | 0 |     info->_.data = data; | 
| 551 | 0 |     return info; | 
| 552 | 0 | } | 
| 553 |  |  | 
| 554 |  | OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) | 
| 555 | 0 | { | 
| 556 | 0 |     OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL); | 
| 557 |  | 
 | 
| 558 | 0 |     if (info == NULL) { | 
| 559 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 560 | 0 |         return NULL; | 
| 561 | 0 |     } | 
| 562 |  |  | 
| 563 | 0 |     info->_.name.name = name; | 
| 564 | 0 |     info->_.name.desc = NULL; | 
| 565 |  | 
 | 
| 566 | 0 |     return info; | 
| 567 | 0 | } | 
| 568 |  |  | 
| 569 |  | int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) | 
| 570 | 0 | { | 
| 571 | 0 |     if (info->type != OSSL_STORE_INFO_NAME) { | 
| 572 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); | 
| 573 | 0 |         return 0; | 
| 574 | 0 |     } | 
| 575 |  |  | 
| 576 | 0 |     info->_.name.desc = desc; | 
| 577 |  | 
 | 
| 578 | 0 |     return 1; | 
| 579 | 0 | } | 
| 580 |  | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) | 
| 581 | 0 | { | 
| 582 | 0 |     OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params); | 
| 583 |  | 
 | 
| 584 | 0 |     if (info == NULL) | 
| 585 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 586 | 0 |     return info; | 
| 587 | 0 | } | 
| 588 |  |  | 
| 589 |  | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey) | 
| 590 | 0 | { | 
| 591 | 0 |     OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey); | 
| 592 |  | 
 | 
| 593 | 0 |     if (info == NULL) | 
| 594 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 595 | 0 |     return info; | 
| 596 | 0 | } | 
| 597 |  |  | 
| 598 |  | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) | 
| 599 | 0 | { | 
| 600 | 0 |     OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey); | 
| 601 |  | 
 | 
| 602 | 0 |     if (info == NULL) | 
| 603 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 604 | 0 |     return info; | 
| 605 | 0 | } | 
| 606 |  |  | 
| 607 |  | OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) | 
| 608 | 0 | { | 
| 609 | 0 |     OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509); | 
| 610 |  | 
 | 
| 611 | 0 |     if (info == NULL) | 
| 612 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 613 | 0 |     return info; | 
| 614 | 0 | } | 
| 615 |  |  | 
| 616 |  | OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) | 
| 617 | 0 | { | 
| 618 | 0 |     OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl); | 
| 619 |  | 
 | 
| 620 | 0 |     if (info == NULL) | 
| 621 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 622 | 0 |     return info; | 
| 623 | 0 | } | 
| 624 |  |  | 
| 625 |  | /* | 
| 626 |  |  * Functions to try to extract data from a OSSL_STORE_INFO. | 
| 627 |  |  */ | 
| 628 |  | int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info) | 
| 629 | 0 | { | 
| 630 | 0 |     return info->type; | 
| 631 | 0 | } | 
| 632 |  |  | 
| 633 |  | void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info) | 
| 634 | 0 | { | 
| 635 | 0 |     if (info->type == type) | 
| 636 | 0 |         return info->_.data; | 
| 637 | 0 |     return NULL; | 
| 638 | 0 | } | 
| 639 |  |  | 
| 640 |  | const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) | 
| 641 | 0 | { | 
| 642 | 0 |     if (info->type == OSSL_STORE_INFO_NAME) | 
| 643 | 0 |         return info->_.name.name; | 
| 644 | 0 |     return NULL; | 
| 645 | 0 | } | 
| 646 |  |  | 
| 647 |  | char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) | 
| 648 | 0 | { | 
| 649 | 0 |     if (info->type == OSSL_STORE_INFO_NAME) { | 
| 650 | 0 |         char *ret = OPENSSL_strdup(info->_.name.name); | 
| 651 |  | 
 | 
| 652 | 0 |         if (ret == NULL) | 
| 653 | 0 |             ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 654 | 0 |         return ret; | 
| 655 | 0 |     } | 
| 656 | 0 |     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); | 
| 657 | 0 |     return NULL; | 
| 658 | 0 | } | 
| 659 |  |  | 
| 660 |  | const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info) | 
| 661 | 0 | { | 
| 662 | 0 |     if (info->type == OSSL_STORE_INFO_NAME) | 
| 663 | 0 |         return info->_.name.desc; | 
| 664 | 0 |     return NULL; | 
| 665 | 0 | } | 
| 666 |  |  | 
| 667 |  | char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) | 
| 668 | 0 | { | 
| 669 | 0 |     if (info->type == OSSL_STORE_INFO_NAME) { | 
| 670 | 0 |         char *ret = OPENSSL_strdup(info->_.name.desc | 
| 671 | 0 |                                    ? info->_.name.desc : ""); | 
| 672 |  | 
 | 
| 673 | 0 |         if (ret == NULL) | 
| 674 | 0 |             ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 675 | 0 |         return ret; | 
| 676 | 0 |     } | 
| 677 | 0 |     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); | 
| 678 | 0 |     return NULL; | 
| 679 | 0 | } | 
| 680 |  |  | 
| 681 |  | EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info) | 
| 682 | 0 | { | 
| 683 | 0 |     if (info->type == OSSL_STORE_INFO_PARAMS) | 
| 684 | 0 |         return info->_.params; | 
| 685 | 0 |     return NULL; | 
| 686 | 0 | } | 
| 687 |  |  | 
| 688 |  | EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info) | 
| 689 | 0 | { | 
| 690 | 0 |     if (info->type == OSSL_STORE_INFO_PARAMS) { | 
| 691 | 0 |         EVP_PKEY_up_ref(info->_.params); | 
| 692 | 0 |         return info->_.params; | 
| 693 | 0 |     } | 
| 694 | 0 |     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS); | 
| 695 | 0 |     return NULL; | 
| 696 | 0 | } | 
| 697 |  |  | 
| 698 |  | EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info) | 
| 699 | 0 | { | 
| 700 | 0 |     if (info->type == OSSL_STORE_INFO_PUBKEY) | 
| 701 | 0 |         return info->_.pubkey; | 
| 702 | 0 |     return NULL; | 
| 703 | 0 | } | 
| 704 |  |  | 
| 705 |  | EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info) | 
| 706 | 0 | { | 
| 707 | 0 |     if (info->type == OSSL_STORE_INFO_PUBKEY) { | 
| 708 | 0 |         EVP_PKEY_up_ref(info->_.pubkey); | 
| 709 | 0 |         return info->_.pubkey; | 
| 710 | 0 |     } | 
| 711 | 0 |     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PUBLIC_KEY); | 
| 712 | 0 |     return NULL; | 
| 713 | 0 | } | 
| 714 |  |  | 
| 715 |  | EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info) | 
| 716 | 0 | { | 
| 717 | 0 |     if (info->type == OSSL_STORE_INFO_PKEY) | 
| 718 | 0 |         return info->_.pkey; | 
| 719 | 0 |     return NULL; | 
| 720 | 0 | } | 
| 721 |  |  | 
| 722 |  | EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info) | 
| 723 | 0 | { | 
| 724 | 0 |     if (info->type == OSSL_STORE_INFO_PKEY) { | 
| 725 | 0 |         EVP_PKEY_up_ref(info->_.pkey); | 
| 726 | 0 |         return info->_.pkey; | 
| 727 | 0 |     } | 
| 728 | 0 |     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY); | 
| 729 | 0 |     return NULL; | 
| 730 | 0 | } | 
| 731 |  |  | 
| 732 |  | X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info) | 
| 733 | 0 | { | 
| 734 | 0 |     if (info->type == OSSL_STORE_INFO_CERT) | 
| 735 | 0 |         return info->_.x509; | 
| 736 | 0 |     return NULL; | 
| 737 | 0 | } | 
| 738 |  |  | 
| 739 |  | X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info) | 
| 740 | 0 | { | 
| 741 | 0 |     if (info->type == OSSL_STORE_INFO_CERT) { | 
| 742 | 0 |         X509_up_ref(info->_.x509); | 
| 743 | 0 |         return info->_.x509; | 
| 744 | 0 |     } | 
| 745 | 0 |     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE); | 
| 746 | 0 |     return NULL; | 
| 747 | 0 | } | 
| 748 |  |  | 
| 749 |  | X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info) | 
| 750 | 0 | { | 
| 751 | 0 |     if (info->type == OSSL_STORE_INFO_CRL) | 
| 752 | 0 |         return info->_.crl; | 
| 753 | 0 |     return NULL; | 
| 754 | 0 | } | 
| 755 |  |  | 
| 756 |  | X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info) | 
| 757 | 0 | { | 
| 758 | 0 |     if (info->type == OSSL_STORE_INFO_CRL) { | 
| 759 | 0 |         X509_CRL_up_ref(info->_.crl); | 
| 760 | 0 |         return info->_.crl; | 
| 761 | 0 |     } | 
| 762 | 0 |     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL); | 
| 763 | 0 |     return NULL; | 
| 764 | 0 | } | 
| 765 |  |  | 
| 766 |  | /* | 
| 767 |  |  * Free the OSSL_STORE_INFO | 
| 768 |  |  */ | 
| 769 |  | void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) | 
| 770 | 0 | { | 
| 771 | 0 |     if (info != NULL) { | 
| 772 | 0 |         switch (info->type) { | 
| 773 | 0 |         case OSSL_STORE_INFO_NAME: | 
| 774 | 0 |             OPENSSL_free(info->_.name.name); | 
| 775 | 0 |             OPENSSL_free(info->_.name.desc); | 
| 776 | 0 |             break; | 
| 777 | 0 |         case OSSL_STORE_INFO_PARAMS: | 
| 778 | 0 |             EVP_PKEY_free(info->_.params); | 
| 779 | 0 |             break; | 
| 780 | 0 |         case OSSL_STORE_INFO_PUBKEY: | 
| 781 | 0 |             EVP_PKEY_free(info->_.pubkey); | 
| 782 | 0 |             break; | 
| 783 | 0 |         case OSSL_STORE_INFO_PKEY: | 
| 784 | 0 |             EVP_PKEY_free(info->_.pkey); | 
| 785 | 0 |             break; | 
| 786 | 0 |         case OSSL_STORE_INFO_CERT: | 
| 787 | 0 |             X509_free(info->_.x509); | 
| 788 | 0 |             break; | 
| 789 | 0 |         case OSSL_STORE_INFO_CRL: | 
| 790 | 0 |             X509_CRL_free(info->_.crl); | 
| 791 | 0 |             break; | 
| 792 | 0 |         } | 
| 793 | 0 |         OPENSSL_free(info); | 
| 794 | 0 |     } | 
| 795 | 0 | } | 
| 796 |  |  | 
| 797 |  | int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type) | 
| 798 | 0 | { | 
| 799 | 0 |     int ret = 0; | 
| 800 |  | 
 | 
| 801 | 0 |     if (ctx->fetched_loader != NULL) { | 
| 802 | 0 |         void *provctx = | 
| 803 | 0 |             ossl_provider_ctx(OSSL_STORE_LOADER_get0_provider(ctx->fetched_loader)); | 
| 804 | 0 |         const OSSL_PARAM *params; | 
| 805 | 0 |         const OSSL_PARAM *p_subject = NULL; | 
| 806 | 0 |         const OSSL_PARAM *p_issuer = NULL; | 
| 807 | 0 |         const OSSL_PARAM *p_serial = NULL; | 
| 808 | 0 |         const OSSL_PARAM *p_fingerprint = NULL; | 
| 809 | 0 |         const OSSL_PARAM *p_alias = NULL; | 
| 810 |  | 
 | 
| 811 | 0 |         if (ctx->fetched_loader->p_settable_ctx_params == NULL) | 
| 812 | 0 |             return 0; | 
| 813 |  |  | 
| 814 | 0 |         params = ctx->fetched_loader->p_settable_ctx_params(provctx); | 
| 815 | 0 |         p_subject = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); | 
| 816 | 0 |         p_issuer = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ISSUER); | 
| 817 | 0 |         p_serial = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SERIAL); | 
| 818 | 0 |         p_fingerprint = | 
| 819 | 0 |             OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_FINGERPRINT); | 
| 820 | 0 |         p_alias = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ALIAS); | 
| 821 |  | 
 | 
| 822 | 0 |         switch (search_type) { | 
| 823 | 0 |         case OSSL_STORE_SEARCH_BY_NAME: | 
| 824 | 0 |             ret = (p_subject != NULL); | 
| 825 | 0 |             break; | 
| 826 | 0 |         case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: | 
| 827 | 0 |             ret = (p_issuer != NULL && p_serial != NULL); | 
| 828 | 0 |             break; | 
| 829 | 0 |         case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: | 
| 830 | 0 |             ret = (p_fingerprint != NULL); | 
| 831 | 0 |             break; | 
| 832 | 0 |         case OSSL_STORE_SEARCH_BY_ALIAS: | 
| 833 | 0 |             ret = (p_alias != NULL); | 
| 834 | 0 |             break; | 
| 835 | 0 |         } | 
| 836 | 0 |     } | 
| 837 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 838 | 0 |     if (ctx->fetched_loader == NULL) { | 
| 839 | 0 |         OSSL_STORE_SEARCH tmp_search; | 
| 840 |  | 
 | 
| 841 | 0 |         if (ctx->loader->find == NULL) | 
| 842 | 0 |             return 0; | 
| 843 | 0 |         tmp_search.search_type = search_type; | 
| 844 | 0 |         ret = ctx->loader->find(NULL, &tmp_search); | 
| 845 | 0 |     } | 
| 846 | 0 | #endif | 
| 847 | 0 |     return ret; | 
| 848 | 0 | } | 
| 849 |  |  | 
| 850 |  | /* Search term constructors */ | 
| 851 |  | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) | 
| 852 | 0 | { | 
| 853 | 0 |     OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | 
| 854 |  | 
 | 
| 855 | 0 |     if (search == NULL) { | 
| 856 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 857 | 0 |         return NULL; | 
| 858 | 0 |     } | 
| 859 |  |  | 
| 860 | 0 |     search->search_type = OSSL_STORE_SEARCH_BY_NAME; | 
| 861 | 0 |     search->name = name; | 
| 862 | 0 |     return search; | 
| 863 | 0 | } | 
| 864 |  |  | 
| 865 |  | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, | 
| 866 |  |                                                       const ASN1_INTEGER *serial) | 
| 867 | 0 | { | 
| 868 | 0 |     OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | 
| 869 |  | 
 | 
| 870 | 0 |     if (search == NULL) { | 
| 871 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 872 | 0 |         return NULL; | 
| 873 | 0 |     } | 
| 874 |  |  | 
| 875 | 0 |     search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; | 
| 876 | 0 |     search->name = name; | 
| 877 | 0 |     search->serial = serial; | 
| 878 | 0 |     return search; | 
| 879 | 0 | } | 
| 880 |  |  | 
| 881 |  | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, | 
| 882 |  |                                                         const unsigned char | 
| 883 |  |                                                         *bytes, size_t len) | 
| 884 | 0 | { | 
| 885 | 0 |     OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | 
| 886 |  | 
 | 
| 887 | 0 |     if (search == NULL) { | 
| 888 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 889 | 0 |         return NULL; | 
| 890 | 0 |     } | 
| 891 |  |  | 
| 892 | 0 |     if (digest != NULL && len != (size_t)EVP_MD_get_size(digest)) { | 
| 893 | 0 |         ERR_raise_data(ERR_LIB_OSSL_STORE, | 
| 894 | 0 |                        OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST, | 
| 895 | 0 |                        "%s size is %d, fingerprint size is %zu", | 
| 896 | 0 |                        EVP_MD_get0_name(digest), EVP_MD_get_size(digest), len); | 
| 897 | 0 |         OPENSSL_free(search); | 
| 898 | 0 |         return NULL; | 
| 899 | 0 |     } | 
| 900 |  |  | 
| 901 | 0 |     search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; | 
| 902 | 0 |     search->digest = digest; | 
| 903 | 0 |     search->string = bytes; | 
| 904 | 0 |     search->stringlength = len; | 
| 905 | 0 |     return search; | 
| 906 | 0 | } | 
| 907 |  |  | 
| 908 |  | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) | 
| 909 | 0 | { | 
| 910 | 0 |     OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | 
| 911 |  | 
 | 
| 912 | 0 |     if (search == NULL) { | 
| 913 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 914 | 0 |         return NULL; | 
| 915 | 0 |     } | 
| 916 |  |  | 
| 917 | 0 |     search->search_type = OSSL_STORE_SEARCH_BY_ALIAS; | 
| 918 | 0 |     search->string = (const unsigned char *)alias; | 
| 919 | 0 |     search->stringlength = strlen(alias); | 
| 920 | 0 |     return search; | 
| 921 | 0 | } | 
| 922 |  |  | 
| 923 |  | /* Search term destructor */ | 
| 924 |  | void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search) | 
| 925 | 0 | { | 
| 926 | 0 |     OPENSSL_free(search); | 
| 927 | 0 | } | 
| 928 |  |  | 
| 929 |  | /* Search term accessors */ | 
| 930 |  | int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion) | 
| 931 | 0 | { | 
| 932 | 0 |     return criterion->search_type; | 
| 933 | 0 | } | 
| 934 |  |  | 
| 935 |  | X509_NAME *OSSL_STORE_SEARCH_get0_name(const OSSL_STORE_SEARCH *criterion) | 
| 936 | 0 | { | 
| 937 | 0 |     return criterion->name; | 
| 938 | 0 | } | 
| 939 |  |  | 
| 940 |  | const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH | 
| 941 |  |                                                   *criterion) | 
| 942 | 0 | { | 
| 943 | 0 |     return criterion->serial; | 
| 944 | 0 | } | 
| 945 |  |  | 
| 946 |  | const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH | 
| 947 |  |                                                   *criterion, size_t *length) | 
| 948 | 0 | { | 
| 949 | 0 |     *length = criterion->stringlength; | 
| 950 | 0 |     return criterion->string; | 
| 951 | 0 | } | 
| 952 |  |  | 
| 953 |  | const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion) | 
| 954 | 0 | { | 
| 955 | 0 |     return (const char *)criterion->string; | 
| 956 | 0 | } | 
| 957 |  |  | 
| 958 |  | const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion) | 
| 959 | 0 | { | 
| 960 | 0 |     return criterion->digest; | 
| 961 | 0 | } | 
| 962 |  |  | 
| 963 |  | OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, | 
| 964 |  |                                   OSSL_LIB_CTX *libctx, const char *propq, | 
| 965 |  |                                   const UI_METHOD *ui_method, void *ui_data, | 
| 966 |  |                                   const OSSL_PARAM params[], | 
| 967 |  |                                   OSSL_STORE_post_process_info_fn post_process, | 
| 968 |  |                                   void *post_process_data) | 
| 969 | 0 | { | 
| 970 | 0 |     const OSSL_STORE_LOADER *loader = NULL; | 
| 971 | 0 |     OSSL_STORE_LOADER *fetched_loader = NULL; | 
| 972 | 0 |     OSSL_STORE_LOADER_CTX *loader_ctx = NULL; | 
| 973 | 0 |     OSSL_STORE_CTX *ctx = NULL; | 
| 974 |  | 
 | 
| 975 | 0 |     if (scheme == NULL) | 
| 976 | 0 |         scheme = "file"; | 
| 977 |  | 
 | 
| 978 | 0 |     OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); | 
| 979 | 0 |     ERR_set_mark(); | 
| 980 | 0 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | 
| 981 | 0 |     if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) | 
| 982 | 0 |         loader_ctx = loader->attach(loader, bp, libctx, propq, | 
| 983 | 0 |                                     ui_method, ui_data); | 
| 984 | 0 | #endif | 
| 985 | 0 |     if (loader == NULL | 
| 986 | 0 |         && (fetched_loader = | 
| 987 | 0 |             OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) { | 
| 988 | 0 |         const OSSL_PROVIDER *provider = | 
| 989 | 0 |             OSSL_STORE_LOADER_get0_provider(fetched_loader); | 
| 990 | 0 |         void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); | 
| 991 | 0 |         OSSL_CORE_BIO *cbio = ossl_core_bio_new_from_bio(bp); | 
| 992 |  | 
 | 
| 993 | 0 |         if (cbio == NULL | 
| 994 | 0 |             || (loader_ctx = fetched_loader->p_attach(provctx, cbio)) == NULL) { | 
| 995 | 0 |             OSSL_STORE_LOADER_free(fetched_loader); | 
| 996 | 0 |             fetched_loader = NULL; | 
| 997 | 0 |         } else if (!loader_set_params(fetched_loader, loader_ctx, | 
| 998 | 0 |                                       params, propq)) { | 
| 999 | 0 |             (void)fetched_loader->p_close(loader_ctx); | 
| 1000 | 0 |             OSSL_STORE_LOADER_free(fetched_loader); | 
| 1001 | 0 |             fetched_loader = NULL; | 
| 1002 | 0 |         } | 
| 1003 | 0 |         loader = fetched_loader; | 
| 1004 | 0 |         ossl_core_bio_free(cbio); | 
| 1005 | 0 |     } | 
| 1006 |  | 
 | 
| 1007 | 0 |     if (loader_ctx == NULL) { | 
| 1008 | 0 |         ERR_clear_last_mark(); | 
| 1009 | 0 |         return NULL; | 
| 1010 | 0 |     } | 
| 1011 |  |  | 
| 1012 | 0 |     if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { | 
| 1013 | 0 |         ERR_clear_last_mark(); | 
| 1014 | 0 |         ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | 
| 1015 | 0 |         return NULL; | 
| 1016 | 0 |     } | 
| 1017 |  |  | 
| 1018 | 0 |     if (ui_method != NULL | 
| 1019 | 0 |         && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) { | 
| 1020 | 0 |         ERR_clear_last_mark(); | 
| 1021 | 0 |         OPENSSL_free(ctx); | 
| 1022 | 0 |         return NULL; | 
| 1023 | 0 |     } | 
| 1024 |  |  | 
| 1025 | 0 |     ctx->fetched_loader = fetched_loader; | 
| 1026 | 0 |     ctx->loader = loader; | 
| 1027 | 0 |     ctx->loader_ctx = loader_ctx; | 
| 1028 | 0 |     ctx->post_process = post_process; | 
| 1029 | 0 |     ctx->post_process_data = post_process_data; | 
| 1030 |  |  | 
| 1031 |  |     /* | 
| 1032 |  |      * ossl_store_get0_loader_int will raise an error if the loader for the | 
| 1033 |  |      * the scheme cannot be retrieved. But if a loader was successfully | 
| 1034 |  |      * fetched then we remove this error from the error stack. | 
| 1035 |  |      */ | 
| 1036 | 0 |     ERR_pop_to_mark(); | 
| 1037 |  | 
 | 
| 1038 | 0 |     return ctx; | 
| 1039 | 0 | } |