OSSL_STORE: Make it possible to attach an OSSL_STORE to an opened BIO

This capability existed internally, and is now made public.

Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/11756)
This commit is contained in:
Richard Levitte 2018-10-12 16:46:41 +02:00
parent 78906fff4a
commit 6ab6ecfd6d
13 changed files with 210 additions and 114 deletions

View File

@ -948,6 +948,7 @@ OCSP_F_OCSP_MATCH_ISSUERID:109:ocsp_match_issuerid
OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign
OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify
OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic
OSSL_STORE_F_FILE_ATTACH:128:
OSSL_STORE_F_FILE_CTRL:129:file_ctrl
OSSL_STORE_F_FILE_FIND:138:file_find
OSSL_STORE_F_FILE_GET_PASS:118:file_get_pass
@ -955,10 +956,8 @@ OSSL_STORE_F_FILE_LOAD:119:file_load
OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode
OSSL_STORE_F_FILE_NAME_TO_URI:126:file_name_to_uri
OSSL_STORE_F_FILE_OPEN:120:file_open
OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO:127:ossl_store_attach_pem_bio
OSSL_STORE_F_OSSL_STORE_ATTACH:127:
OSSL_STORE_F_OSSL_STORE_EXPECT:130:OSSL_STORE_expect
OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT:128:\
ossl_store_file_attach_pem_bio_int
OSSL_STORE_F_OSSL_STORE_FIND:131:OSSL_STORE_find
OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT:100:ossl_store_get0_loader_int
OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT:101:OSSL_STORE_INFO_get1_CERT

View File

@ -39,8 +39,8 @@ EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL)
return NULL;
if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u, libctx,
propq)) == NULL)
if ((ctx = OSSL_STORE_attach(bp, libctx, "file", propq, ui_method, u,
NULL, NULL)) == NULL)
goto err;
#ifndef OPENSSL_NO_SECURE_HEAP
{
@ -56,13 +56,14 @@ EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
break;
}
OSSL_STORE_INFO_free(info);
info = NULL;
}
if (ret != NULL && x != NULL)
*x = ret;
err:
ossl_store_detach_pem_bio(ctx);
OSSL_STORE_close(ctx);
UI_destroy_method(ui_method);
OSSL_STORE_INFO_free(info);
return ret;
@ -105,7 +106,8 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
OSSL_STORE_CTX *ctx = NULL;
OSSL_STORE_INFO *info = NULL;
if ((ctx = ossl_store_attach_pem_bio(bp, UI_null(), NULL, NULL, NULL)) == NULL)
if ((ctx = OSSL_STORE_attach(bp, NULL, "file", NULL, UI_null(), NULL,
NULL, NULL)) == NULL)
goto err;
while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) {
@ -114,13 +116,14 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
break;
}
OSSL_STORE_INFO_free(info);
info = NULL;
}
if (ret != NULL && x != NULL)
*x = ret;
err:
ossl_store_detach_pem_bio(ctx);
OSSL_STORE_close(ctx);
OSSL_STORE_INFO_free(info);
return ret;
}
@ -198,7 +201,8 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL)
return NULL;
if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u, NULL, NULL)) == NULL)
if ((ctx = OSSL_STORE_attach(bp, NULL, "file", NULL, ui_method, u,
NULL, NULL)) == NULL)
goto err;
while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) {
@ -211,13 +215,14 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
}
}
OSSL_STORE_INFO_free(info);
info = NULL;
}
if (ret != NULL && x != NULL)
*x = ret;
err:
ossl_store_detach_pem_bio(ctx);
OSSL_STORE_close(ctx);
UI_destroy_method(ui_method);
OSSL_STORE_INFO_free(info);
return ret;

View File

@ -718,6 +718,7 @@ struct ossl_store_loader_ctx_st {
} type;
int errcnt;
#define FILE_FLAG_SECMEM (1<<0)
#define FILE_FLAG_ATTACHED (1<<1)
unsigned int flags;
union {
struct { /* Used with is_raw and is_pem */
@ -774,6 +775,23 @@ static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx)
OPENSSL_free(ctx);
}
static int file_find_type(OSSL_STORE_LOADER_CTX *ctx)
{
BIO *buff = NULL;
char peekbuf[4096] = { 0, };
if ((buff = BIO_new(BIO_f_buffer())) == NULL)
return 0;
ctx->_.file.file = BIO_push(buff, ctx->_.file.file);
if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) {
peekbuf[sizeof(peekbuf) - 1] = '\0';
if (strstr(peekbuf, "-----BEGIN ") != NULL)
ctx->type = is_pem;
}
return 1;
}
static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
const char *uri,
const UI_METHOD *ui_method,
@ -891,22 +909,10 @@ static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
}
ctx->_.dir.end_reached = 1;
}
} else {
BIO *buff = NULL;
char peekbuf[4096] = { 0, };
if ((buff = BIO_new(BIO_f_buffer())) == NULL
|| (ctx->_.file.file = BIO_new_file(path, "rb")) == NULL) {
BIO_free_all(buff);
goto err;
}
ctx->_.file.file = BIO_push(buff, ctx->_.file.file);
if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) {
peekbuf[sizeof(peekbuf) - 1] = '\0';
if (strstr(peekbuf, "-----BEGIN ") != NULL)
ctx->type = is_pem;
}
} else if ((ctx->_.file.file = BIO_new_file(path, "rb")) == NULL
|| !file_find_type(ctx)) {
BIO_free_all(ctx->_.file.file);
goto err;
}
return ctx;
@ -915,6 +921,34 @@ static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
return NULL;
}
static OSSL_STORE_LOADER_CTX *file_attach(const OSSL_STORE_LOADER *loader,
BIO *bp, OPENSSL_CTX *libctx,
const char *propq,
const UI_METHOD *ui_method,
void *ui_data)
{
OSSL_STORE_LOADER_CTX *ctx;
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL
|| (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)) {
OSSL_STOREerr(OSSL_STORE_F_FILE_ATTACH, ERR_R_MALLOC_FAILURE);
OSSL_STORE_LOADER_CTX_free(ctx);
return NULL;
}
ctx->libctx = libctx;
ctx->flags |= FILE_FLAG_ATTACHED;
ctx->_.file.file = bp;
if (!file_find_type(ctx)) {
/* Safety measure */
ctx->_.file.file = NULL;
OSSL_STORE_LOADER_CTX_free(ctx);
ctx = NULL;
}
return ctx;
}
static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
{
int ret = 1;
@ -984,36 +1018,6 @@ static int file_find(OSSL_STORE_LOADER_CTX *ctx,
return 0;
}
/* Internal function to decode an already opened PEM file */
OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp,
OPENSSL_CTX *libctx,
const char *propq)
{
OSSL_STORE_LOADER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx == NULL) {
OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT,
ERR_R_MALLOC_FAILURE);
return NULL;
}
ctx->_.file.file = bp;
ctx->type = is_pem;
ctx->libctx = libctx;
if (propq != NULL) {
ctx->propq = OPENSSL_strdup(propq);
if (ctx->propq == NULL) {
OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT,
ERR_R_MALLOC_FAILURE);
OPENSSL_free(ctx);
return NULL;
}
}
return ctx;
}
static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
const char *pem_name,
const char *pem_header,
@ -1435,17 +1439,25 @@ static int file_eof(OSSL_STORE_LOADER_CTX *ctx)
static int file_close(OSSL_STORE_LOADER_CTX *ctx)
{
if (ctx->type == is_dir) {
OPENSSL_DIR_end(&ctx->_.dir.ctx);
if ((ctx->flags & FILE_FLAG_ATTACHED) == 0) {
if (ctx->type == is_dir)
OPENSSL_DIR_end(&ctx->_.dir.ctx);
else
BIO_free_all(ctx->_.file.file);
} else {
BIO_free_all(ctx->_.file.file);
}
OSSL_STORE_LOADER_CTX_free(ctx);
return 1;
}
/*
* Because file_attach() called file_find_type(), we know that a
* BIO_f_buffer() has been pushed on top of the regular BIO.
*/
BIO *buff = ctx->_.file.file;
int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx)
{
/* Detach buff */
(void)BIO_pop(ctx->_.file.file);
/* Safety measure */
ctx->_.file.file = NULL;
BIO_free(buff);
}
OSSL_STORE_LOADER_CTX_free(ctx);
return 1;
}
@ -1455,6 +1467,7 @@ static OSSL_STORE_LOADER file_loader =
"file",
NULL,
file_open,
file_attach,
file_ctrl,
file_expect,
file_find,

View File

@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy

View File

@ -651,47 +651,33 @@ char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info)
return NULL;
}
OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method,
void *ui_data, OPENSSL_CTX *libctx,
const char *propq)
OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, OPENSSL_CTX *libctx,
const char *scheme, const char *propq,
const UI_METHOD *ui_method, void *ui_data,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_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, libctx,
propq)) == NULL))
goto done;
if ((loader =
ossl_store_get0_loader_int(scheme != NULL ? scheme : "file")) == NULL
|| (loader_ctx = loader->attach(loader, bp, libctx, propq,
ui_method, ui_data)) == NULL)
return NULL;
if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO,
ERR_R_MALLOC_FAILURE);
goto done;
OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH, ERR_R_MALLOC_FAILURE);
return NULL;
}
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;
ctx->post_process = post_process;
ctx->post_process_data = post_process_data;
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;
}

View File

@ -102,6 +102,7 @@ struct ossl_store_loader_st {
const char *scheme;
ENGINE *engine;
OSSL_STORE_open_fn open;
OSSL_STORE_attach_fn attach;
OSSL_STORE_ctrl_fn ctrl;
OSSL_STORE_expect_fn expect;
OSSL_STORE_find_fn find;
@ -122,13 +123,3 @@ void ossl_store_destroy_loaders_int(void);
int ossl_store_init_once(void);
int ossl_store_file_loader_init(void);
/*-
* 'file' scheme stuff
* -------------------
*/
OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp,
OPENSSL_CTX *libctx,
const char *propq);
int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx);

View File

@ -71,6 +71,13 @@ int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader,
return 1;
}
int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader,
OSSL_STORE_attach_fn attach_function)
{
loader->attach = attach_function;
return 1;
}
int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader,
OSSL_STORE_ctrl_fn ctrl_function)
{

View File

@ -4,12 +4,14 @@
OSSL_STORE_LOADER, OSSL_STORE_LOADER_CTX, OSSL_STORE_LOADER_new,
OSSL_STORE_LOADER_get0_engine, OSSL_STORE_LOADER_get0_scheme,
OSSL_STORE_LOADER_set_open, OSSL_STORE_LOADER_set_ctrl,
OSSL_STORE_LOADER_set_expect, OSSL_STORE_LOADER_set_find,
OSSL_STORE_LOADER_set_load, OSSL_STORE_LOADER_set_eof,
OSSL_STORE_LOADER_set_error, OSSL_STORE_LOADER_set_close,
OSSL_STORE_LOADER_set_open, OSSL_STORE_LOADER_set_attach,
OSSL_STORE_LOADER_set_ctrl, OSSL_STORE_LOADER_set_expect,
OSSL_STORE_LOADER_set_find, OSSL_STORE_LOADER_set_load,
OSSL_STORE_LOADER_set_eof, OSSL_STORE_LOADER_set_error,
OSSL_STORE_LOADER_set_close,
OSSL_STORE_LOADER_free, OSSL_STORE_register_loader,
OSSL_STORE_unregister_loader, OSSL_STORE_open_fn, OSSL_STORE_ctrl_fn,
OSSL_STORE_unregister_loader,
OSSL_STORE_open_fn, OSSL_STORE_attach_fn, OSSL_STORE_ctrl_fn,
OSSL_STORE_expect_fn, OSSL_STORE_find_fn,
OSSL_STORE_load_fn, OSSL_STORE_eof_fn, OSSL_STORE_error_fn,
OSSL_STORE_close_fn - Types and functions to manipulate, register and
@ -35,6 +37,16 @@ unregister STORE loaders for different URI schemes
void *ui_data);
int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *store_loader,
OSSL_STORE_open_fn store_open_function);
typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_attach_fn)(const OSSL_STORE_LOADER
*loader,
BIO *bio,
OPENSSL_CTX *libctx,
const char *propq,
const UI_METHOD
*ui_method,
void *ui_data);
int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader,
OSSL_STORE_attach_fn attach_function);
typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd,
va_list args);
int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *store_loader,
@ -99,6 +111,10 @@ initialized, to create a private data store (B<OSSL_STORE_LOADER_CTX>, see
above), and to return it.
If something goes wrong, this function is expected to return NULL.
=item B<OSSL_STORE_open_fn>
This function takes a B<BIO>, otherwise works like B<OSSL_STORE_open_fn>.
=item B<OSSL_STORE_ctrl_fn>
This function takes a B<OSSL_STORE_LOADER_CTX> pointer, a command number
@ -189,6 +205,9 @@ OSSL_STORE_LOADER_get0_scheme() returns the scheme of the B<store_loader>.
OSSL_STORE_LOADER_set_open() sets the opener function for the
B<store_loader>.
OSSL_STORE_LOADER_set_attach() sets the attacher function for the
B<store_loader>.
OSSL_STORE_LOADER_set_ctrl() sets the control function for the
B<store_loader>.

View File

@ -0,0 +1,45 @@
=pod
=head1 NAME
OSSL_STORE_attach - Functions to read objects from a BIO
=head1 SYNOPSIS
#include <openssl/store.h>
OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, OPENSSL_CTX *libctx,
const char *scheme, const char *propq,
const UI_METHOD *ui_method, void *ui_data,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data);
=head1 DESCRIPTION
OSSL_STORE_attach() works like L<OSSL_STORE_open(3)>, except it takes a B<BIO>
I<bio> instead of a I<uri>, along with a I<scheme> to determine what loader
should be used to process the data.
=head1 RETURN VALUES
OSSL_STORE_attach() returns a pointer to a B<OSSL_STORE_CTX> on success, or
NULL on failure.
=head1 SEE ALSO
L<ossl_store(7)>, L<OSSL_STORE_open(3)>
=head1 HISTORY
OSSL_STORE_attach() was added in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2020 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
in the file LICENSE in the source distribution or at
L<https://www.openssl.org/source/license.html>.
=cut

View File

@ -102,6 +102,24 @@ int OSSL_STORE_error(OSSL_STORE_CTX *ctx);
*/
int OSSL_STORE_close(OSSL_STORE_CTX *ctx);
/*
* Attach to a BIO. This works like OSSL_STORE_open() except it takes a
* BIO instead of a uri, along with a scheme to use when reading.
* The given UI method will be used any time the loader needs extra input,
* for example when a password or pin is needed, and will be passed the
* same user data every time it's needed in this context.
*
* Returns a context reference which represents the channel to communicate
* through.
*
* Note that this function is considered unsafe, all depending on what the
* BIO actually reads.
*/
OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, OPENSSL_CTX *libctx,
const char *scheme, const char *propq,
const UI_METHOD *ui_method, void *ui_data,
OSSL_STORE_post_process_info_fn post_process,
void *post_process_data);
/*-
* Extracting OpenSSL types from and creating new OSSL_STORE_INFOs
@ -228,6 +246,16 @@ typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_open_fn)(const OSSL_STORE_LOADER
void *ui_data);
int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader,
OSSL_STORE_open_fn open_function);
typedef OSSL_STORE_LOADER_CTX *(*OSSL_STORE_attach_fn)(const OSSL_STORE_LOADER
*loader,
BIO *bio,
OPENSSL_CTX *libctx,
const char *propq,
const UI_METHOD
*ui_method,
void *ui_data);
int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader,
OSSL_STORE_attach_fn attach_function);
typedef int (*OSSL_STORE_ctrl_fn)(OSSL_STORE_LOADER_CTX *ctx, int cmd,
va_list args);
int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader,

View File

@ -8,8 +8,8 @@
* https://www.openssl.org/source/license.html
*/
#ifndef OPENSSL_STOREERR_H
# define OPENSSL_STOREERR_H
#ifndef OPENSSL_OSSL_STOREERR_H
# define OPENSSL_OSSL_STOREERR_H
# pragma once
# include <openssl/opensslconf.h>
@ -25,6 +25,7 @@ int ERR_load_OSSL_STORE_strings(void);
* OSSL_STORE function codes.
*/
# ifndef OPENSSL_NO_DEPRECATED_3_0
# define OSSL_STORE_F_FILE_ATTACH 0
# define OSSL_STORE_F_FILE_CTRL 0
# define OSSL_STORE_F_FILE_FIND 0
# define OSSL_STORE_F_FILE_GET_PASS 0
@ -32,9 +33,8 @@ int ERR_load_OSSL_STORE_strings(void);
# define OSSL_STORE_F_FILE_LOAD_TRY_DECODE 0
# define OSSL_STORE_F_FILE_NAME_TO_URI 0
# define OSSL_STORE_F_FILE_OPEN 0
# define OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO 0
# define OSSL_STORE_F_OSSL_STORE_ATTACH 0
# define OSSL_STORE_F_OSSL_STORE_EXPECT 0
# define OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT 0
# define OSSL_STORE_F_OSSL_STORE_FIND 0
# define OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT 0
# define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT 0

View File

@ -5086,3 +5086,5 @@ EVP_default_properties_is_fips_enabled ? 3_0_0 EXIST::FUNCTION:
EVP_default_properties_enable_fips ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_new_raw_private_key_with_libctx ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_new_raw_public_key_with_libctx ? 3_0_0 EXIST::FUNCTION:
OSSL_STORE_attach ? 3_0_0 EXIST::FUNCTION:
OSSL_STORE_LOADER_set_attach ? 3_0_0 EXIST::FUNCTION:

View File

@ -49,6 +49,7 @@ OSSL_STORE_INFO datatype
OSSL_STORE_LOADER datatype
OSSL_STORE_LOADER_CTX datatype
OSSL_STORE_SEARCH datatype
OSSL_STORE_attach_fn datatype
OSSL_STORE_close_fn datatype
OSSL_STORE_ctrl_fn datatype
OSSL_STORE_expect_fn datatype