+int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type)
+{
+ OSSL_STORE_SEARCH tmp_search;
+
+ if (ctx->loader->find == NULL)
+ return 0;
+ tmp_search.search_type = search_type;
+ return ctx->loader->find(NULL, &tmp_search);
+}
+
+/* Search term constructors */
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_NAME;
+ search->name = name;
+ return search;
+}
+
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name,
+ const ASN1_INTEGER *serial)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL;
+ search->name = name;
+ search->serial = serial;
+ return search;
+}
+
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest,
+ const unsigned char
+ *bytes, size_t len)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (digest != NULL && len != (size_t)EVP_MD_size(digest)) {
+ char buf1[20], buf2[20];
+
+ BIO_snprintf(buf1, sizeof(buf1), "%d", EVP_MD_size(digest));
+ BIO_snprintf(buf2, sizeof(buf2), "%zu", len);
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT,
+ OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST);
+ ERR_add_error_data(5, EVP_MD_name(digest), " size is ", buf1,
+ ", fingerprint size is ", buf2);
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT;
+ search->digest = digest;
+ search->string = bytes;
+ search->stringlength = len;
+ return search;
+}
+
+OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias)
+{
+ OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search));
+
+ if (search == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ search->search_type = OSSL_STORE_SEARCH_BY_ALIAS;
+ search->string = (const unsigned char *)alias;
+ search->stringlength = strlen(alias);
+ return search;
+}
+
+/* Search term destructor */
+void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search)
+{
+ OPENSSL_free(search);
+}
+
+/* Search term accessors */
+int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion)
+{
+ return criterion->search_type;
+}
+
+X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion)
+{
+ return criterion->name;
+}
+
+const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH
+ *criterion)
+{
+ return criterion->serial;
+}
+
+const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH
+ *criterion, size_t *length)
+{
+ *length = criterion->stringlength;
+ return criterion->string;
+}
+
+const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion)
+{
+ return (const char *)criterion->string;
+}
+
+const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion)
+{
+ return criterion->digest;
+}
+
+/* Internal functions */
+OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
+ BUF_MEM *embedded)
+{
+ OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL);
+
+ if (info == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
+ ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ info->_.embedded.blob = embedded;
+ info->_.embedded.pem_name =
+ new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
+
+ if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED,
+ ERR_R_MALLOC_FAILURE);
+ OSSL_STORE_INFO_free(info);
+ info = NULL;
+ }
+
+ return info;
+}
+
+BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info)
+{
+ if (info->type == OSSL_STORE_INFO_EMBEDDED)
+ return info->_.embedded.blob;
+ return NULL;
+}
+
+char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
+{
+ if (info->type == OSSL_STORE_INFO_EMBEDDED)
+ return info->_.embedded.pem_name;
+ return NULL;
+}
+
+OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
+ void *ui_data)
+{
+ OSSL_STORE_CTX *ctx = NULL;
+ const OSSL_STORE_LOADER *loader = NULL;
+ OSSL_STORE_LOADER_CTX *loader_ctx = NULL;
+
+ if ((loader = ossl_store_get0_loader_int("file")) == NULL
+ || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL))
+ goto done;
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
+ OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO,
+ ERR_R_MALLOC_FAILURE);
+ goto done;
+ }
+
+ ctx->loader = loader;
+ ctx->loader_ctx = loader_ctx;
+ loader_ctx = NULL;
+ ctx->ui_method = ui_method;
+ ctx->ui_data = ui_data;
+ ctx->post_process = NULL;
+ ctx->post_process_data = NULL;
+
+ done:
+ if (loader_ctx != NULL)
+ /*
+ * We ignore a returned error because we will return NULL anyway in
+ * this case, so if something goes wrong when closing, that'll simply
+ * just add another entry on the error stack.
+ */
+ (void)loader->close(loader_ctx);
+ return ctx;
+}
+
+int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx)
+{
+ int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx);
+
+ OPENSSL_free(ctx);
+ return loader_ret;
+}