summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2020-07-23 16:56:59 +0200
committerRichard Levitte <levitte@openssl.org>2020-09-03 17:48:32 +0200
commit16feca71544681cabf873fecd3f860f9853bdf07 (patch)
treea1dce6397911d95de73f10208b65dbba04526ac6
parentbd7a6f16eb52c5c022b2555810efd99006db0a02 (diff)
downloadopenssl-new-16feca71544681cabf873fecd3f860f9853bdf07.tar.gz
STORE: Move the built-in 'file:' loader to become an engine module
From this point on, this engine must be specifically specified. To replace the internal EMBEDDED hack with something unique for the new module, functions to create application specific OSSL_STORE_INFO types were added. Furthermore, the following function had to be exported: ossl_do_blob_header() ossl_do_PVK_header() asn1_d2i_read_bio() Finally, evp_pkcs82pkey_int() has become public under a new name, EVP_PKCS82PKEY_with_libctx() Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12587)
-rw-r--r--Configurations/unix-Makefile.tmpl2
-rw-r--r--crypto/asn1/a_d2i_fp.c1
-rw-r--r--crypto/asn1/d2i_param.c3
-rw-r--r--crypto/asn1/d2i_pr.c4
-rw-r--r--crypto/evp/evp_pkey.c6
-rw-r--r--crypto/store/build.info2
-rw-r--r--crypto/store/store_init.c3
-rw-r--r--crypto/store/store_lib.c63
-rw-r--r--crypto/store/store_local.h24
-rw-r--r--crypto/store/store_result.c2
-rw-r--r--crypto/x509/x_all.c2
-rw-r--r--doc/man3/OSSL_STORE_INFO.pod23
-rw-r--r--engines/build.info10
-rw-r--r--engines/e_loader_attic.c (renamed from crypto/store/loader_file.c)419
-rw-r--r--engines/e_loader_attic.ec3
-rw-r--r--engines/e_loader_attic.txt23
-rw-r--r--engines/e_loader_attic_err.c73
-rw-r--r--engines/e_loader_attic_err.h43
-rw-r--r--include/crypto/asn1.h2
-rw-r--r--include/crypto/evp.h2
-rw-r--r--include/internal/asn1.h15
-rw-r--r--include/openssl/store.h2
-rw-r--r--include/openssl/x509.h2
-rw-r--r--providers/implementations/encode_decode/decode_common.c2
-rw-r--r--util/libcrypto.num8
-rw-r--r--util/missingcrypto-internal.txt5
-rw-r--r--util/missingcrypto.txt1
27 files changed, 504 insertions, 241 deletions
diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
index 441f83c345..ff4803be74 100644
--- a/Configurations/unix-Makefile.tmpl
+++ b/Configurations/unix-Makefile.tmpl
@@ -1075,6 +1075,8 @@ errors:
include/internal/o_dir.h
include/internal/err.h
include/internal/evp.h
+ include/internal/pem.h
+ include/internal/asn1.h
include/internal/sslconf.h );
our @cryptoskipheaders = ( @sslheaders,
qw( include/openssl/conf_api.h
diff --git a/crypto/asn1/a_d2i_fp.c b/crypto/asn1/a_d2i_fp.c
index 186e7ec413..249e6294c8 100644
--- a/crypto/asn1/a_d2i_fp.c
+++ b/crypto/asn1/a_d2i_fp.c
@@ -13,6 +13,7 @@
#include "internal/numbers.h"
#include <openssl/buffer.h>
#include <openssl/asn1.h>
+#include "internal/asn1.h"
#include "crypto/asn1.h"
#ifndef NO_OLD_ASN1
diff --git a/crypto/asn1/d2i_param.c b/crypto/asn1/d2i_param.c
index bd6ef1ce51..f0217b47f6 100644
--- a/crypto/asn1/d2i_param.c
+++ b/crypto/asn1/d2i_param.c
@@ -11,8 +11,9 @@
#include "internal/cryptlib.h"
#include <openssl/evp.h>
#include <openssl/asn1.h>
-#include "crypto/evp.h"
+#include "internal/asn1.h"
#include "crypto/asn1.h"
+#include "crypto/evp.h"
EVP_PKEY *d2i_KeyParams(int type, EVP_PKEY **a, const unsigned char **pp,
long length)
diff --git a/crypto/asn1/d2i_pr.c b/crypto/asn1/d2i_pr.c
index a4d240e7c4..ba81782698 100644
--- a/crypto/asn1/d2i_pr.c
+++ b/crypto/asn1/d2i_pr.c
@@ -55,7 +55,7 @@ EVP_PKEY *d2i_PrivateKey_ex(int type, EVP_PKEY **a, const unsigned char **pp,
p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
if (p8 == NULL)
goto err;
- tmp = evp_pkcs82pkey_int(p8, libctx, propq);
+ tmp = EVP_PKCS82PKEY_with_libctx(p8, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8);
if (tmp == NULL)
goto err;
@@ -122,7 +122,7 @@ EVP_PKEY *d2i_AutoPrivateKey_ex(EVP_PKEY **a, const unsigned char **pp,
ASN1err(0, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return NULL;
}
- ret = evp_pkcs82pkey_int(p8, libctx, propq);
+ ret = EVP_PKCS82PKEY_with_libctx(p8, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8);
if (ret == NULL)
return NULL;
diff --git a/crypto/evp/evp_pkey.c b/crypto/evp/evp_pkey.c
index cfe0544ed6..92ae3e5fe8 100644
--- a/crypto/evp/evp_pkey.c
+++ b/crypto/evp/evp_pkey.c
@@ -18,8 +18,8 @@
/* Extract a private key from a PKCS8 structure */
-EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx,
- const char *propq)
+EVP_PKEY *EVP_PKCS82PKEY_with_libctx(const PKCS8_PRIV_KEY_INFO *p8,
+ OPENSSL_CTX *libctx, const char *propq)
{
EVP_PKEY *pkey = NULL;
const ASN1_OBJECT *algoid;
@@ -64,7 +64,7 @@ EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx,
EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8)
{
- return evp_pkcs82pkey_int(p8, NULL, NULL);
+ return EVP_PKCS82PKEY_with_libctx(p8, NULL, NULL);
}
/* Turn a private key into a PKCS8 structure */
diff --git a/crypto/store/build.info b/crypto/store/build.info
index 33b59f0fae..bd19237ba4 100644
--- a/crypto/store/build.info
+++ b/crypto/store/build.info
@@ -1,4 +1,4 @@
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
store_err.c store_lib.c store_result.c store_strings.c store_meth.c \
- store_init.c store_register.c loader_file.c
+ store_init.c store_register.c
diff --git a/crypto/store/store_init.c b/crypto/store/store_init.c
index b87730736d..4d434eb57b 100644
--- a/crypto/store/store_init.c
+++ b/crypto/store/store_init.c
@@ -14,8 +14,7 @@
static CRYPTO_ONCE store_init = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(do_store_init)
{
- return OPENSSL_init_crypto(0, NULL)
- && ossl_store_file_loader_init();
+ return OPENSSL_init_crypto(0, NULL);
}
int ossl_store_init_once(void)
diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c
index d0fdb38cd8..1c718c589e 100644
--- a/crypto/store/store_lib.c
+++ b/crypto/store/store_lib.c
@@ -474,7 +474,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx)
* In all cases, ownership of the object is transferred to the OSSL_STORE_INFO
* and will therefore be freed when the OSSL_STORE_INFO is freed.
*/
-static OSSL_STORE_INFO *store_info_new(int type, void *data)
+OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data)
{
OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info));
@@ -488,7 +488,7 @@ static OSSL_STORE_INFO *store_info_new(int type, void *data)
OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name)
{
- OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL);
+ OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL);
if (info == NULL) {
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
@@ -514,7 +514,7 @@ int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc)
}
OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params)
{
- OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params);
+ OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params);
if (info == NULL)
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
@@ -523,7 +523,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params)
OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey)
{
- OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PUBKEY, pkey);
+ OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey);
if (info == NULL)
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
@@ -532,7 +532,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey)
OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey)
{
- OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey);
+ OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey);
if (info == NULL)
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
@@ -541,7 +541,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey)
OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509)
{
- OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509);
+ OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509);
if (info == NULL)
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
@@ -550,7 +550,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509)
OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl)
{
- OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl);
+ OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl);
if (info == NULL)
ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE);
@@ -565,6 +565,13 @@ int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info)
return info->type;
}
+void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info)
+{
+ if (info->type == type)
+ return info->_.data;
+ return NULL;
+}
+
const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info)
{
if (info->type == OSSL_STORE_INFO_NAME)
@@ -698,10 +705,6 @@ void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info)
{
if (info != NULL) {
switch (info->type) {
- case OSSL_STORE_INFO_EMBEDDED:
- BUF_MEM_free(info->_.embedded.blob);
- OPENSSL_free(info->_.embedded.pem_name);
- break;
case OSSL_STORE_INFO_NAME:
OPENSSL_free(info->_.name.name);
OPENSSL_free(info->_.name.desc);
@@ -889,44 +892,6 @@ 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) {
- ERR_raise(ERR_LIB_OSSL_STORE, 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) {
- ERR_raise(ERR_LIB_OSSL_STORE, 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(BIO *bp, const char *scheme,
OPENSSL_CTX *libctx, const char *propq,
const UI_METHOD *ui_method, void *ui_data,
diff --git a/crypto/store/store_local.h b/crypto/store/store_local.h
index 619e547aae..cdd9f164b4 100644
--- a/crypto/store/store_local.h
+++ b/crypto/store/store_local.h
@@ -29,11 +29,6 @@ struct ossl_store_info_st {
void *data; /* used internally as generic pointer */
struct {
- BUF_MEM *blob;
- char *pem_name;
- } embedded; /* when type == OSSL_STORE_INFO_EMBEDDED */
-
- struct {
char *name;
char *desc;
} name; /* when type == OSSL_STORE_INFO_NAME */
@@ -45,26 +40,8 @@ struct ossl_store_info_st {
X509_CRL *crl; /* when type == OSSL_STORE_INFO_CRL */
} _;
};
-
DEFINE_STACK_OF(OSSL_STORE_INFO)
-/*
- * EMBEDDED is a special type of OSSL_STORE_INFO, specially for the file
- * handlers. It should never reach a calling application or any engine.
- * However, it can be used by a FILE_HANDLER's try_decode function to signal
- * that it has decoded the incoming blob into a new blob, and that the
- * attempted decoding should be immediately restarted with the new blob, using
- * the new PEM name.
- */
-/*
- * Because this is an internal type, we don't make it public.
- */
-#define OSSL_STORE_INFO_EMBEDDED -1
-OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name,
- BUF_MEM *embedded);
-BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info);
-char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info);
-
/*-
* OSSL_STORE_SEARCH stuff
* -----------------------
@@ -174,7 +151,6 @@ struct ossl_store_ctx_st {
*/
int ossl_store_init_once(void);
-int ossl_store_file_loader_init(void);
/*-
* 'file' scheme stuff
diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c
index 74aeaf543b..9df29cec0a 100644
--- a/crypto/store/store_result.c
+++ b/crypto/store/store_result.c
@@ -302,7 +302,7 @@ static EVP_PKEY *try_key_value_legacy(struct extracted_param_data_st *data,
derp = der;
p8info = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, der_len);
if (p8info != NULL) {
- pk = evp_pkcs82pkey_int(p8info, libctx, propq);
+ pk = EVP_PKCS82PKEY_with_libctx(p8info, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8info);
}
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index a8ad292074..3e7dc42ef1 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -23,7 +23,7 @@
#include <openssl/rsa.h>
#include <openssl/dsa.h>
#include <openssl/x509v3.h>
-#include "crypto/asn1.h"
+#include "internal/asn1.h"
#include "crypto/pkcs7.h"
#include "crypto/x509.h"
diff --git a/doc/man3/OSSL_STORE_INFO.pod b/doc/man3/OSSL_STORE_INFO.pod
index bc965a77bd..8c811ec1f3 100644
--- a/doc/man3/OSSL_STORE_INFO.pod
+++ b/doc/man3/OSSL_STORE_INFO.pod
@@ -12,7 +12,8 @@ OSSL_STORE_INFO_get1_PKEY, OSSL_STORE_INFO_get1_CERT, OSSL_STORE_INFO_get1_CRL,
OSSL_STORE_INFO_type_string, OSSL_STORE_INFO_free,
OSSL_STORE_INFO_new_NAME, OSSL_STORE_INFO_set0_NAME_description,
OSSL_STORE_INFO_new_PARAMS, OSSL_STORE_INFO_new_PUBKEY,
-OSSL_STORE_INFO_new_PKEY, OSSL_STORE_INFO_new_CERT, OSSL_STORE_INFO_new_CRL
+OSSL_STORE_INFO_new_PKEY, OSSL_STORE_INFO_new_CERT, OSSL_STORE_INFO_new_CRL,
+OSSL_STORE_INFO_new, OSSL_STORE_INFO_get0_data
- Functions to manipulate OSSL_STORE_INFO objects
=head1 SYNOPSIS
@@ -50,6 +51,9 @@ OSSL_STORE_INFO_new_PKEY, OSSL_STORE_INFO_new_CERT, OSSL_STORE_INFO_new_CRL
OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509);
OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl);
+ OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data);
+ void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info);
+
=head1 DESCRIPTION
These functions are primarily useful for applications to retrieve
@@ -110,6 +114,19 @@ description.
This description is meant to be human readable and should be used for
information printout.
+OSSL_STORE_INFO_new() creates a B<OSSL_STORE_INFO> with an arbitrary I<type>
+number and I<data> structure. It's the responsibility of the caller to
+define type numbers other than the ones defined by F<< <openssl/store.h> >>,
+and to handle freeing the associated data structure on their own.
+I<Using type numbers that are defined by F<< <openssl/store.h> >> may cause
+undefined behaviours, including crashes>.
+
+OSSL_STORE_INFO_get0_data() returns the data pointer that was passed to
+OSSL_STORE_INFO_new() if I<type> matches the type number in I<info>.
+
+OSSL_STORE_INFO_new() and OSSL_STORE_INFO_get0_data() may be useful for
+applications that define their own STORE data, but must be used with care.
+
=head1 SUPPORTED OBJECTS
Currently supported object types are:
@@ -177,13 +194,13 @@ OSSL_STORE_INFO_get1_PARAMS(), OSSL_STORE_INFO_get1_PKEY(),
OSSL_STORE_INFO_get1_CERT() and OSSL_STORE_INFO_get1_CRL() all return
a pointer to a duplicate of the OpenSSL object on success, NULL otherwise.
-OSSL_STORE_INFO_type_string() returns a string on success, or B<NULL> on
+OSSL_STORE_INFO_type_string() returns a string on success, or NULL on
failure.
OSSL_STORE_INFO_new_NAME(), OSSL_STORE_INFO_new_PARAMS(),
OSSL_STORE_INFO_new_PKEY(), OSSL_STORE_INFO_new_CERT() and
OSSL_STORE_INFO_new_CRL() return a B<OSSL_STORE_INFO>
-pointer on success, or B<NULL> on failure.
+pointer on success, or NULL on failure.
OSSL_STORE_INFO_set0_NAME_description() returns 1 on success, or 0 on
failure.
diff --git a/engines/build.info b/engines/build.info
index 3bfe1dc057..4e83dbf9bc 100644
--- a/engines/build.info
+++ b/engines/build.info
@@ -70,7 +70,7 @@ IF[{- !$disabled{"engine"} -}]
ENDIF
ENDIF
- MODULES{noinst,engine}=ossltest dasync
+ MODULES{noinst,engine}=ossltest dasync loader_attic
SOURCE[dasync]=e_dasync.c
DEPEND[dasync]=../libcrypto
INCLUDE[dasync]=../include
@@ -86,6 +86,14 @@ IF[{- !$disabled{"engine"} -}]
SOURCE[ossltest]=ossltest.ld
GENERATE[ossltest.ld]=../util/engines.num
ENDIF
+
+ SOURCE[loader_attic]=e_loader_attic.c
+ DEPEND[loader_attic]=../libcrypto
+ INCLUDE[loader_attic]=../include
+ IF[{- defined $target{shared_defflag} -}]
+ SOURCE[loader_attic]=loader_attic.ld
+ GENERATE[loader_attic.ld]=../util/engines.num
+ ENDIF
ENDIF
GENERATE[e_padlock-x86.s]=asm/e_padlock-x86.pl
GENERATE[e_padlock-x86_64.s]=asm/e_padlock-x86_64.pl
diff --git a/crypto/store/loader_file.c b/engines/e_loader_attic.c
index 25ce9ba92e..581bfb0285 100644
--- a/crypto/store/loader_file.c
+++ b/engines/e_loader_attic.c
@@ -7,10 +7,12 @@
* https://www.openssl.org/source/license.html
*/
+/* THIS ENGINE IS FOR TESTING PURPOSES ONLY. */
+
/* We need to use some engine deprecated APIs */
#define OPENSSL_SUPPRESS_DEPRECATED
-#include "e_os.h"
+/* #include "e_os.h" */
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
@@ -21,25 +23,26 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
-#include "internal/pem.h"
#include <openssl/pkcs12.h> /* For the PKCS8 stuff o.O */
#include <openssl/rsa.h> /* For d2i_RSAPrivateKey */
#include <openssl/safestack.h>
#include <openssl/store.h>
#include <openssl/ui.h>
+#include <openssl/engine.h>
#include <openssl/x509.h> /* For the PKCS8 stuff o.O */
-#include "crypto/asn1.h"
-#include "crypto/ctype.h"
+#include "internal/asn1.h" /* For asn1_d2i_read_bio */
+#include "internal/pem.h" /* For PVK and "blob" PEM headers */
#include "internal/o_dir.h"
#include "internal/cryptlib.h"
-#include "crypto/store.h"
-#include "crypto/evp.h"
-#include "store_local.h"
+
+#include "e_loader_attic_err.c"
DEFINE_STACK_OF(X509)
+DEFINE_STACK_OF(OSSL_STORE_INFO)
#ifdef _WIN32
# define stat _stat
+# define strncasecmp _strnicmp
#endif
#ifndef S_ISDIR
@@ -59,7 +62,7 @@ static char *file_get_pass(const UI_METHOD *ui_method, char *pass,
char *prompt = NULL;
if (ui == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -68,21 +71,20 @@ static char *file_get_pass(const UI_METHOD *ui_method, char *pass,
UI_add_user_data(ui, data);
if ((prompt = UI_construct_prompt(ui, desc, info)) == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
pass = NULL;
} else if (!UI_add_input_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD,
pass, 0, maxsize - 1)) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_UI_LIB);
+ ATTICerr(0, ERR_R_UI_LIB);
pass = NULL;
} else {
switch (UI_process(ui)) {
case -2:
- OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS,
- OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED);
+ ATTICerr(0, ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED);
pass = NULL;
break;
case -1:
- OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_UI_LIB);
+ ATTICerr(0, ERR_R_UI_LIB);
pass = NULL;
break;
default:
@@ -126,6 +128,91 @@ static int file_get_pem_pass(char *buf, int num, int w, void *data)
return pass == NULL ? 0 : strlen(pass);
}
+/*
+ * Check if |str| ends with |suffix| preceded by a space, and if it does,
+ * return the index of that space. If there is no such suffix in |str|,
+ * return -1.
+ * For |str| == "FOO BAR" and |suffix| == "BAR", the returned value is 3.
+ */
+static int check_suffix(const char *str, const char *suffix)
+{
+ int str_len = strlen(str);
+ int suffix_len = strlen(suffix) + 1;
+ const char *p = NULL;
+
+ if (suffix_len >= str_len)
+ return -1;
+ p = str + str_len - suffix_len;
+ if (*p != ' '
+ || strcmp(p + 1, suffix) != 0)
+ return -1;
+ return p - str;
+}
+
+/*
+ * EMBEDDED is a special type of OSSL_STORE_INFO, specially for the file
+ * handlers, so we define it internally. This uses the possibility to
+ * create an OSSL_STORE_INFO with a generic data pointer and arbitrary
+ * type number.
+ *
+ * This is used by a FILE_HANDLER's try_decode function to signal that it
+ * has decoded the incoming blob into a new blob, and that the attempted
+ * decoding should be immediately restarted with the new blob, using the
+ * new PEM name.
+ */
+/* Negative numbers are never used for public OSSL_STORE_INFO types */
+#define STORE_INFO_EMBEDDED -1
+
+/* This is the embedded data */
+struct embedded_st {
+ BUF_MEM *blob;
+ char *pem_name;
+};
+
+/* Helper functions */
+static struct embedded_st *get0_EMBEDDED(OSSL_STORE_INFO *info)
+{
+ return OSSL_STORE_INFO_get0_data(STORE_INFO_EMBEDDED, info);
+}
+
+static void store_info_free(OSSL_STORE_INFO *info)
+{
+ struct embedded_st *data;
+
+ if (info != NULL && (data = get0_EMBEDDED(info)) != NULL) {
+ BUF_MEM_free(data->blob);
+ OPENSSL_free(data->pem_name);
+ OPENSSL_free(data);
+ }
+ OSSL_STORE_INFO_free(info);
+}
+
+static OSSL_STORE_INFO *new_EMBEDDED(const char *new_pem_name,
+ BUF_MEM *embedded)
+{
+ OSSL_STORE_INFO *info = NULL;
+ struct embedded_st *data = NULL;
+
+ if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL
+ || (info = OSSL_STORE_INFO_new(STORE_INFO_EMBEDDED, data)) == NULL) {
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(data);
+ return NULL;
+ }
+
+ data->pem_name =
+ new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name);
+
+ if (new_pem_name != NULL && data->pem_name == NULL) {
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
+ store_info_free(info);
+ info = NULL;
+ }
+ data->blob = embedded;
+
+ return info;
+}
+
/*-
* The file scheme decoders
* ------------------------
@@ -243,13 +330,11 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
if ((pass = file_get_pass(ui_method, tpass, PEM_BUFSIZE,
"PKCS12 import pass phrase", uri,
ui_data)) == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12,
- OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR);
+ ATTICerr(0, ATTIC_R_PASSPHRASE_CALLBACK_ERROR);
goto p12_end;
}
if (!PKCS12_verify_mac(p12, pass, strlen(pass))) {
- OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS12,
- OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC);
+ ATTICerr(0, ATTIC_R_ERROR_VERIFYING_PKCS12_MAC);
goto p12_end;
}
}
@@ -293,11 +378,11 @@ static OSSL_STORE_INFO *try_decode_PKCS12(const char *pem_name,
EVP_PKEY_free(pkey);
X509_free(cert);
sk_X509_pop_free(chain, X509_free);
- OSSL_STORE_INFO_free(osi_pkey);
- OSSL_STORE_INFO_free(osi_cert);
- OSSL_STORE_INFO_free(osi_ca);
+ store_info_free(osi_pkey);
+ store_info_free(osi_cert);
+ store_info_free(osi_ca);
if (!ok) {
- sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free);
+ sk_OSSL_STORE_INFO_pop_free(ctx, store_info_free);
ctx = NULL;
}
*pctx = ctx;
@@ -325,7 +410,7 @@ static void destroy_ctx_PKCS12(void **pctx)
{
STACK_OF(OSSL_STORE_INFO) *ctx = *pctx;
- sk_OSSL_STORE_INFO_pop_free(ctx, OSSL_STORE_INFO_free);
+ sk_OSSL_STORE_INFO_pop_free(ctx, store_info_free);
*pctx = NULL;
}
@@ -375,16 +460,14 @@ static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name,
*matchcount = 1;
if ((mem = BUF_MEM_new()) == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
- ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
goto nop8;
}
if ((pass = file_get_pass(ui_method, kbuf, PEM_BUFSIZE,
"PKCS8 decrypt pass phrase", uri,
ui_data)) == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
- OSSL_STORE_R_BAD_PASSWORD_READ);
+ ATTICerr(0, ATTIC_R_BAD_PASSWORD_READ);
goto nop8;
}
@@ -397,10 +480,9 @@ static OSSL_STORE_INFO *try_decode_PKCS8Encrypted(const char *pem_name,
mem->max = mem->length = (size_t)new_data_len;
X509_SIG_free(p8);
- store_info = ossl_store_info_new_EMBEDDED(PEM_STRING_PKCS8INF, mem);
+ store_info = new_EMBEDDED(PEM_STRING_PKCS8INF, mem);
if (store_info == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PKCS8ENCRYPTED,
- ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
goto nop8;
}
@@ -421,7 +503,6 @@ static FILE_HANDLER PKCS8Encrypted_handler = {
* encoded ones and old style PEM ones (with the key type is encoded into
* the PEM name).
*/
-int pem_check_suffix(const char *pem_str, const char *suffix);
static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
const char *pem_header,
const unsigned char *blob,
@@ -443,16 +524,19 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
*matchcount = 1;
if (p8inf != NULL)
- pkey = evp_pkcs82pkey_int(p8inf, libctx, propq);
+ pkey = EVP_PKCS82PKEY_with_libctx(p8inf, libctx, propq);
PKCS8_PRIV_KEY_INFO_free(p8inf);
} else {
int slen;
+ int pkey_id;
- if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
+ if ((slen = check_suffix(pem_name, "PRIVATE KEY")) > 0
&& (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name,
- slen)) != NULL) {
+ slen)) != NULL
+ && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+ ameth)) {
*matchcount = 1;
- pkey = d2i_PrivateKey_ex(ameth->pkey_id, NULL, &blob, len,
+ pkey = d2i_PrivateKey_ex(pkey_id, NULL, &blob, len,
libctx, propq);
}
}
@@ -473,17 +557,19 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
EVP_PKEY_ASN1_METHOD *ameth2 = NULL;
EVP_PKEY *tmp_pkey = NULL;
const unsigned char *tmp_blob = blob;
+ int pkey_id, pkey_flags;
- if (!asn1meths(curengine, &ameth2, NULL, nids[i]))
- continue;
- if (ameth2 == NULL
- || ameth2->pkey_flags & ASN1_PKEY_ALIAS)
+ if (!asn1meths(curengine, &ameth2, NULL, nids[i])
+ || !EVP_PKEY_asn1_get0_info(&pkey_id, NULL,
+ &pkey_flags, NULL, NULL,
+ ameth2)
+ || (pkey_flags & ASN1_PKEY_ALIAS) != 0)
continue;
ERR_set_mark(); /* prevent flooding error queue */
- tmp_pkey =
- d2i_PrivateKey_ex(ameth2->pkey_id, NULL,
- &tmp_blob, len, libctx, propq);
+ tmp_pkey = d2i_PrivateKey_ex(pkey_id, NULL,
+ &tmp_blob, len,
+ libctx, propq);
if (tmp_pkey != NULL) {
if (pkey != NULL)
EVP_PKEY_free(tmp_pkey);
@@ -501,13 +587,16 @@ static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
EVP_PKEY *tmp_pkey = NULL;
const unsigned char *tmp_blob = blob;
+ int pkey_id, pkey_flags;
ameth = EVP_PKEY_asn1_get0(i);
- if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+ if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, &pkey_flags, NULL,
+ NULL, ameth)
+ || (pkey_flags & ASN1_PKEY_ALIAS) != 0)
continue;
ERR_set_mark(); /* prevent flooding error queue */
- tmp_pkey = d2i_PrivateKey_ex(ameth->pkey_id, NULL, &tmp_blob, len,
+ tmp_pkey = d2i_PrivateKey_ex(pkey_id, NULL, &tmp_blob, len,
libctx, propq);
if (tmp_pkey != NULL) {
if (pkey != NULL)
@@ -590,69 +679,58 @@ static OSSL_STORE_INFO *try_decode_params(const char *pem_name,
const char *propq)
{
OSSL_STORE_INFO *store_info = NULL;
- int slen = 0;
EVP_PKEY *pkey = NULL;
const EVP_PKEY_ASN1_METHOD *ameth = NULL;
- int ok = 0;
if (pem_name != NULL) {
- if ((slen = pem_check_suffix(pem_name, "PARAMETERS")) == 0)
- return NULL;
- *matchcount = 1;
- }
+ int slen;
+ int pkey_id;
- if (slen > 0) {
- if ((pkey = EVP_PKEY_new()) == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB);
- return NULL;
+ if ((slen = check_suffix(pem_name, "PARAMETERS")) > 0
+ && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, slen)) != NULL
+ && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL,
+ ameth)) {
+ *matchcount = 1;
+ pkey = d2i_KeyParams(pkey_id, NULL, &blob, len);
}
-
-
- if (EVP_PKEY_set_type_str(pkey, pem_name, slen)
- && (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
- && ameth->param_decode != NULL
- && ameth->param_decode(pkey, &blob, len))
- ok = 1;
} else {
int i;
- EVP_PKEY *tmp_pkey = NULL;
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
+ EVP_PKEY *tmp_pkey = NULL;
const unsigned char *tmp_blob = blob;
-
- if (tmp_pkey == NULL && (tmp_pkey = EVP_PKEY_new()) == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB);
- break;
- }
+ int pkey_id, pkey_flags;
ameth = EVP_PKEY_asn1_get0(i);
- if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
+ if (!EVP_PKEY_asn1_get0_info(&pkey_id, NULL, &pkey_flags, NULL,
+ NULL, ameth)
+ || (pkey_flags & ASN1_PKEY_ALIAS) != 0)
continue;
ERR_set_mark(); /* prevent flooding error queue */
- if (EVP_PKEY_set_type(tmp_pkey, ameth->pkey_id)
- && (ameth = EVP_PKEY_get0_asn1(tmp_pkey)) != NULL
- && ameth->param_decode != NULL
- && ameth->param_decode(tmp_pkey, &tmp_blob, len)) {
+ tmp_pkey = d2i_KeyParams(pkey_id, NULL, &tmp_blob, len);
+
+ if (tmp_pkey != NULL) {
if (pkey != NULL)
EVP_PKEY_free(tmp_pkey);
else
pkey = tmp_pkey;
- tmp_pkey = NULL;
(*matchcount)++;
}
ERR_pop_to_mark();
}
- EVP_PKEY_free(tmp_pkey);
- if (*matchcount == 1) {
- ok = 1;
+ if (*matchcount > 1) {
+ EVP_PKEY_free(pkey);
+ pkey = NULL;
}
}
+ if (pkey == NULL)
+ /* No match */
+ return NULL;
- if (ok)
- store_info = OSSL_STORE_INFO_new_PARAMS(pkey);
+ store_info = OSSL_STORE_INFO_new_PARAMS(pkey);
if (store_info == NULL)
EVP_PKEY_free(pkey);
@@ -824,6 +902,7 @@ struct ossl_store_loader_ctx_st {
/* Expected object type. May be unspecified */
int expected_type;
+
OPENSSL_CTX *libctx;
char *propq;
};
@@ -898,7 +977,7 @@ static OSSL_STORE_LOADER_CTX *file_open_with_libctx
} else if (uri[7] == '/') {
p = &uri[7];
} else {
- OSSL_STOREerr(0, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED);
+ ATTICerr(0, ATTIC_R_URI_AUTHORITY_UNSUPPORTED);
return NULL;
}
}
@@ -907,7 +986,7 @@ static OSSL_STORE_LOADER_CTX *file_open_with_libctx
#ifdef _WIN32
/* Windows file: URIs with a drive letter start with a / */
if (p[0] == '/' && p[2] == ':' && p[3] == '/') {
- char c = ossl_tolower(p[1]);
+ char c = tolower(p[1]);
if (c >= 'a' && c <= 'z') {
p++;
@@ -926,7 +1005,7 @@ static OSSL_STORE_LOADER_CTX *file_open_with_libctx
* be absolute. So says RFC 8089
*/
if (path_data[i].check_absolute && path_data[i].path[0] != '/') {
- OSSL_STOREerr(0, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE);
+ ATTICerr(0, ATTIC_R_PATH_MUST_BE_ABSOLUTE);
ERR_add_error_data(1, path_data[i].path);
return NULL;
}
@@ -947,12 +1026,12 @@ static OSSL_STORE_LOADER_CTX *file_open_with_libctx
ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx == NULL) {
- OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
return NULL;
}
ctx->uri = OPENSSL_strdup(uri);
if (ctx->uri == NULL) {
- OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -962,11 +1041,7 @@ static OSSL_STORE_LOADER_CTX *file_open_with_libctx
ctx->_.dir.last_errno = errno;
if (ctx->_.dir.last_entry == NULL) {
if (ctx->_.dir.last_errno != 0) {
- char errbuf[256];
- OSSL_STOREerr(0, ERR_R_SYS_LIB);
- errno = ctx->_.dir.last_errno;
- if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
- ERR_add_error_data(1, errbuf);
+ ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno);
goto err;
}
ctx->_.dir.end_reached = 1;
@@ -979,7 +1054,7 @@ static OSSL_STORE_LOADER_CTX *file_open_with_libctx
if (propq != NULL) {
ctx->propq = OPENSSL_strdup(propq);
if (ctx->propq == NULL) {
- OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -1005,17 +1080,11 @@ static OSSL_STORE_LOADER_CTX *file_attach
{
OSSL_STORE_LOADER_CTX *ctx = NULL;
- if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) {
- OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (propq != NULL) {
- ctx->propq = OPENSSL_strdup(propq);
- if (ctx->propq == NULL) {
- OSSL_STOREerr(0, ERR_R_MALLOC_FAILURE);
- goto err;
- }
+ if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL
+ || (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)) {
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
+ OSSL_STORE_LOADER_CTX_free(ctx);
+ return NULL;
}
ctx->libctx = libctx;
ctx->flags |= FILE_FLAG_ATTACHED;
@@ -1048,7 +1117,7 @@ static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args)
ctx->flags |= FILE_FLAG_SECMEM;
break;
default:
- OSSL_STOREerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
+ ATTICerr(0, ERR_R_PASSED_INVALID_ARGUMENT);
ret = 0;
break;
}
@@ -1082,8 +1151,7 @@ static int file_find(OSSL_STORE_LOADER_CTX *ctx,
return 1;
if (ctx->type != is_dir) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_FIND,
- OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES);
+ ATTICerr(0, ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES);
return 0;
}
@@ -1094,8 +1162,7 @@ static int file_find(OSSL_STORE_LOADER_CTX *ctx,
}
if (ctx != NULL)
- OSSL_STOREerr(OSSL_STORE_F_FILE_FIND,
- OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE);
+ ATTICerr(0, ATTIC_R_UNSUPPORTED_SEARCH_TYPE);
return 0;
}
@@ -1120,8 +1187,7 @@ static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
* OSSL_NELEM(file_handlers));
if (matching_handlers == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD_TRY_DECODE,
- ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1157,8 +1223,8 @@ static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
if ((*matchcount += try_matchcount) > 1) {
/* more than one match => ambiguous, kill any result */
- OSSL_STORE_INFO_free(result);
- OSSL_STORE_INFO_free(tmp_result);
+ store_info_free(result);
+ store_info_free(tmp_result);
if (handler->destroy_ctx != NULL)
handler->destroy_ctx(&handler_ctx);
handler_ctx = NULL;
@@ -1183,13 +1249,18 @@ static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx,
BUF_MEM_free(new_mem);
if (result != NULL
- && (t = OSSL_STORE_INFO_get_type(result)) == OSSL_STORE_INFO_EMBEDDED) {
- pem_name = new_pem_name =
- ossl_store_info_get0_EMBEDDED_pem_name(result);
- new_mem = ossl_store_info_get0_EMBEDDED_buffer(result);
+ && (t = OSSL_STORE_INFO_get_type(result)) == STORE_INFO_EMBEDDED) {
+ struct embedded_st *embedded = get0_EMBEDDED(result);
+
+ /* "steal" the embedded data */
+ pem_name = new_pem_name = embedded->pem_name;
+ new_mem = embedded->blob;
data = (unsigned char *)new_mem->data;
len = new_mem->length;
- OPENSSL_free(result);
+ embedded->pem_name = NULL;
+ embedded->blob = NULL;
+
+ store_info_free(result);
result = NULL;
goto again;
}
@@ -1380,7 +1451,7 @@ static int file_name_to_uri(OSSL_STORE_LOADER_CTX *ctx, const char *name,
*data = OPENSSL_zalloc(calculated_length);
if (*data == NULL) {
- OSSL_STOREerr(OSSL_STORE_F_FILE_NAME_TO_URI, ERR_R_MALLOC_FAILURE);
+ ATTICerr(0, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -1431,9 +1502,9 @@ static int file_name_check(OSSL_STORE_LOADER_CTX *ctx, const char *name)
* Last, check that the rest of the extension is a decimal number, at
* least one digit long.
*/
- if (!ossl_isdigit(*p))
+ if (!isdigit(*p))
return 0;
- while (ossl_isdigit(*p))
+ while (isdigit(*p))
p++;
#ifdef __VMS
@@ -1469,13 +1540,9 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
if (ctx->_.dir.last_entry == NULL) {
if (!ctx->_.dir.end_reached) {
- char errbuf[256];
assert(ctx->_.dir.last_errno != 0);
- OSSL_STOREerr(0, ERR_R_SYS_LIB);
- errno = ctx->_.dir.last_errno;
+ ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno);
ctx->errcnt++;
- if (openssl_strerror_r(errno, errbuf, sizeof(errbuf)))
- ERR_add_error_data(1, errbuf);
}
return NULL;
}
@@ -1499,7 +1566,7 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
if (newname != NULL
&& (result = OSSL_STORE_INFO_new_NAME(newname)) == NULL) {
OPENSSL_free(newname);
- OSSL_STOREerr(0, ERR_R_OSSL_STORE_LIB);
+ ATTICerr(0, ERR_R_OSSL_STORE_LIB);
return NULL;
}
} while (result == NULL && !file_eof(ctx));
@@ -1558,14 +1625,14 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
}
if (matchcount > 1) {
- OSSL_STOREerr(0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE);
+ ATTICerr(0, ATTIC_R_AMBIGUOUS_CONTENT_TYPE);
} else if (matchcount == 1) {
/*
* If there are other errors on the stack, they already show
* what the problem is.
*/
if (ERR_peek_error() == 0) {
- OSSL_STOREerr(0, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE);
+ ATTICerr(0, ATTIC_R_UNSUPPORTED_CONTENT_TYPE);
if (pem_name != NULL)
ERR_add_error_data(3, "PEM type is '", pem_name, "'");
}
@@ -1581,14 +1648,14 @@ static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
/* We bail out on ambiguity */
if (matchcount > 1) {
- OSSL_STORE_INFO_free(result);
+ store_info_free(result);
return NULL;
}
if (result != NULL
&& ctx->expected_type != 0
&& ctx->expected_type != OSSL_STORE_INFO_get_type(result)) {
- OSSL_STORE_INFO_free(result);
+ store_info_free(result);
goto again;
}
}
@@ -1637,31 +1704,87 @@ static int file_close(OSSL_STORE_LOADER_CTX *ctx)
return 1;
}
-static OSSL_STORE_LOADER file_loader =
- {
- "file",
- NULL,
- file_open,
- file_attach,
- file_ctrl,
- file_expect,
- file_find,
- file_load,
- file_eof,
- file_error,
- file_close,
- file_open_with_libctx,
- };
-
-static void store_file_loader_deinit(void)
+/*-
+ * ENGINE management
+ */
+
+static const char *loader_attic_id = "loader_attic";
+static const char *loader_attic_name = "'file:' loader";
+
+static OSSL_STORE_LOADER *loader_attic = NULL;
+
+static int loader_attic_init(ENGINE *e)
{
- ossl_store_unregister_loader_int(file_loader.scheme);
+ return 1;
}
-int ossl_store_file_loader_init(void)
+
+static int loader_attic_finish(ENGINE *e)
{
- int ret = ossl_store_register_loader_int(&file_loader);
+ return 1;
+}
- OPENSSL_atexit(store_file_loader_deinit);
- return ret;
+
+static int loader_attic_destroy(ENGINE *e)
+{
+ OSSL_STORE_LOADER *loader = OSSL_STORE_unregister_loader("file");
+
+ if (loader == NULL)
+ return 0;
+
+ ERR_unload_ATTIC_strings();
+ OSSL_STORE_LOADER_free(loader);
+ return 1;
+}
+
+static int bind_loader_attic(ENGINE *e)
+{
+
+ /* Ensure the ATTIC error handdling is set up on best effort basis */
+ ERR_load_ATTIC_strings();
+
+ if (/* Create the OSSL_STORE_LOADER */
+ (loader_attic = OSSL_STORE_LOADER_new(e, "file")) == NULL
+ || !OSSL_STORE_LOADER_set_open_with_libctx(loader_attic,
+ file_open_with_libctx)
+ || !OSSL_STORE_LOADER_set_open(loader_attic, file_open)
+ || !OSSL_STORE_LOADER_set_attach(loader_attic, file_attach)
+ || !OSSL_STORE_LOADER_set_ctrl(loader_attic, file_ctrl)
+ || !OSSL_STORE_LOADER_set_expect(loader_attic, file_expect)
+ || !OSSL_STORE_LOADER_set_find(loader_attic, file_find)
+ || !OSSL_STORE_LOADER_set_load(loader_attic, file_load)
+ || !OSSL_STORE_LOADER_set_eof(loader_attic, file_eof)
+ || !OSSL_STORE_LOADER_set_error(loader_attic, file_error)
+ || !OSSL_STORE_LOADER_set_close(loader_attic, file_close)
+ /* Init the engine itself */
+ || !ENGINE_set_id(e, loader_attic_id)
+ || !ENGINE_set_name(e, loader_attic_name)
+ || !ENGINE_set_destroy_function(e, loader_attic_destroy)
+ || !ENGINE_set_init_function(e, loader_attic_init)
+ || !ENGINE_set_finish_function(e, loader_attic_finish)
+ /* Finally, register the method with libcrypto */
+ || !OSSL_STORE_register_loader(loader_attic)) {
+ OSSL_STORE_LOADER_free(loader_attic);
+ loader_attic = NULL;
+ ATTICerr(0, ATTIC_R_INIT_FAILED);
+ return 0;
+ }
+
+ return 1;
+}
+
+#ifdef OPENSSL_NO_DYNAMIC_ENGINE
+# error "Only allowed as dynamically shared object"
+#endif
+
+static int bind_helper(ENGINE *e, const char *id)
+{
+ if (id && (strcmp(id, loader_attic_id) != 0))
+ return 0;
+ if (!bind_loader_attic(e))
+ return 0;
+ return 1;
}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+ IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
diff --git a/engines/e_loader_attic.ec b/engines/e_loader_attic.ec
new file mode 100644
index 0000000000..525a689fe5
--- /dev/null
+++ b/engines/e_loader_attic.ec
@@ -0,0 +1,3 @@
+# The INPUT HEADER is scanned for declarations
+# LIBNAME INPUT HEADER ERROR-TABLE FILE
+L ATTIC e_loader_attic_err.h e_loader_attic_err.c
diff --git a/engines/e_loader_attic.txt b/engines/e_loader_attic.txt
new file mode 100644
index 0000000000..db1a996a33
--- /dev/null
+++ b/engines/e_loader_attic.txt
@@ -0,0 +1,23 @@
+# Copyright 1999-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
+# https://www.openssl.org/source/license.html
+
+# Function codes
+
+#Reason codes
+ATTIC_R_AMBIGUOUS_CONTENT_TYPE:100:ambiguous content type
+ATTIC_R_BAD_PASSWORD_READ:101:bad password read
+ATTIC_R_ERROR_VERIFYING_PKCS12_MAC:102:error verifying pkcs12 mac
+ATTIC_R_INIT_FAILED:103:init failed
+ATTIC_R_PASSPHRASE_CALLBACK_ERROR:104:passphrase callback error
+ATTIC_R_PATH_MUST_BE_ABSOLUTE:105:path must be absolute
+ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES:106:\
+ search only supported for directories
+ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED:107:\
+ ui process interrupted or cancelled
+ATTIC_R_UNSUPPORTED_CONTENT_TYPE:108:unsupported content type
+ATTIC_R_UNSUPPORTED_SEARCH_TYPE:109:unsupported search type
+ATTIC_R_URI_AUTHORITY_UNSUPPORTED:110:uri authority unsupported
diff --git a/engines/e_loader_attic_err.c b/engines/e_loader_attic_err.c
new file mode 100644
index 0000000000..2bc4e854c8
--- /dev/null
+++ b/engines/e_loader_attic_err.c
@@ -0,0 +1,73 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/err.h>
+#include "e_loader_attic_err.h"
+
+#ifndef OPENSSL_NO_ERR
+
+static ERR_STRING_DATA ATTIC_str_reasons[] = {
+ {ERR_PACK(0, 0, ATTIC_R_AMBIGUOUS_CONTENT_TYPE), "ambiguous content type"},
+ {ERR_PACK(0, 0, ATTIC_R_BAD_PASSWORD_READ), "bad password read"},
+ {ERR_PACK(0, 0, ATTIC_R_ERROR_VERIFYING_PKCS12_MAC),
+ "error verifying pkcs12 mac"},
+ {ERR_PACK(0, 0, ATTIC_R_INIT_FAILED), "init failed"},
+ {ERR_PACK(0, 0, ATTIC_R_PASSPHRASE_CALLBACK_ERROR),
+ "passphrase callback error"},
+ {ERR_PACK(0, 0, ATTIC_R_PATH_MUST_BE_ABSOLUTE), "path must be absolute"},
+ {ERR_PACK(0, 0, ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES),
+ "search only supported for directories"},
+ {ERR_PACK(0, 0, ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED),
+ "ui process interrupted or cancelled"},
+ {ERR_PACK(0, 0, ATTIC_R_UNSUPPORTED_CONTENT_TYPE),
+ "unsupported content type"},
+ {ERR_PACK(0, 0, ATTIC_R_UNSUPPORTED_SEARCH_TYPE),
+ "unsupported search type"},
+ {ERR_PACK(0, 0, ATTIC_R_URI_AUTHORITY_UNSUPPORTED),
+ "uri authority unsupported"},
+ {0, NULL}
+};
+
+#endif
+
+static int lib_code = 0;
+static int error_loaded = 0;
+
+static int ERR_load_ATTIC_strings(void)
+{
+ if (lib_code == 0)
+ lib_code = ERR_get_next_error_library();
+
+ if (!error_loaded) {
+#ifndef OPENSSL_NO_ERR
+ ERR_load_strings(lib_code, ATTIC_str_reasons);
+#endif
+ error_loaded = 1;
+ }
+ return 1;
+}
+
+static void ERR_unload_ATTIC_strings(void)
+{
+ if (error_loaded) {
+#ifndef OPENSSL_NO_ERR
+ ERR_unload_strings(lib_code, ATTIC_str_reasons);
+#endif
+ error_loaded = 0;
+ }
+}
+
+static void ERR_ATTIC_error(int function, int reason, char *file, int line)
+{
+ if (lib_code == 0)
+ lib_code = ERR_get_next_error_library();
+ ERR_raise(lib_code, reason);
+ ERR_set_debug(file, line, NULL);
+}
diff --git a/engines/e_loader_attic_err.h b/engines/e_loader_attic_err.h
new file mode 100644
index 0000000000..115e0ea6f6
--- /dev/null
+++ b/engines/e_loader_attic_err.h
@@ -0,0 +1,43 @@
+/*
+ * Generated by util/mkerr.pl DO NOT EDIT
+ * 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OPENSSL_ATTICERR_H
+# define OPENSSL_ATTICERR_H
+# pragma once
+
+# include <openssl/opensslconf.h>
+# include <openssl/symhacks.h>
+
+
+# define ATTICerr(f, r) ERR_ATTIC_error(0, (r), OPENSSL_FILE, OPENSSL_LINE)
+
+
+/*
+ * ATTIC function codes.
+ */
+# ifndef OPENSSL_NO_DEPRECATED_3_0
+# endif
+
+/*
+ * ATTIC reason codes.
+ */
+# define ATTIC_R_AMBIGUOUS_CONTENT_TYPE 100
+# define ATTIC_R_BAD_PASSWORD_READ 101
+# define ATTIC_R_ERROR_VERIFYING_PKCS12_MAC 102
+# define ATTIC_R_INIT_FAILED 103
+# define ATTIC_R_PASSPHRASE_CALLBACK_ERROR 104
+# define ATTIC_R_PATH_MUST_BE_ABSOLUTE 105
+# define ATTIC_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 106
+# define ATTIC_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 107
+# define ATTIC_R_UNSUPPORTED_CONTENT_TYPE 108
+# define ATTIC_R_UNSUPPORTED_SEARCH_TYPE 109
+# define ATTIC_R_URI_AUTHORITY_UNSUPPORTED 110
+
+#endif
diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h
index 041642f022..624df3cb05 100644
--- a/include/crypto/asn1.h
+++ b/include/crypto/asn1.h
@@ -124,5 +124,3 @@ struct asn1_pctx_st {
unsigned long oid_flags;
unsigned long str_flags;
} /* ASN1_PCTX */ ;
-
-int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
diff --git a/include/crypto/evp.h b/include/crypto/evp.h
index 634eb86425..b00634234c 100644
--- a/include/crypto/evp.h
+++ b/include/crypto/evp.h
@@ -763,8 +763,6 @@ int pkcs5_pbkdf2_hmac_with_libctx(const char *pass, int passlen,
int evp_pkey_ctx_set_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
int evp_pkey_ctx_get_params_strict(EVP_PKEY_CTX *ctx, OSSL_PARAM *params);
-EVP_PKEY *evp_pkcs82pkey_int(const PKCS8_PRIV_KEY_INFO *p8, OPENSSL_CTX *libctx,
- const char *propq);
EVP_MD_CTX *evp_md_ctx_new_with_libctx(EVP_PKEY *pkey,
const ASN1_OCTET_STRING *id,
OPENSSL_CTX *libctx, const char *propq);
diff --git a/include/internal/asn1.h b/include/internal/asn1.h
new file mode 100644
index 0000000000..8448786919
--- /dev/null
+++ b/include/internal/asn1.h
@@ -0,0 +1,15 @@
+/*
+ * 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
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_INTERNAL_ASN1_H
+# define OSSL_INTERNAL_ASN1_H
+
+int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
+
+#endif
diff --git a/include/openssl/store.h b/include/openssl/store.h
index 9a2b423371..b2201cacaa 100644
--- a/include/openssl/store.h
+++ b/include/openssl/store.h
@@ -151,6 +151,7 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bio, const char *scheme,
* In all cases, ownership of the object is transferred to the OSSL_STORE_INFO
* and will therefore be freed when the OSSL_STORE_INFO is freed.
*/
+OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data);
OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name);
int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc);
OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params);
@@ -163,6 +164,7 @@ OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl);
* Functions to try to extract data from a OSSL_STORE_INFO.
*/
int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info);
+void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info);
const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info);
char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info);
const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info);
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 9aef28c954..d243fda94c 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -1035,6 +1035,8 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
EVP_PKEY *EVP_PKCS82PKEY(const PKCS8_PRIV_KEY_INFO *p8);
+EVP_PKEY *EVP_PKCS82PKEY_with_libctx(const PKCS8_PRIV_KEY_INFO *p8,
+ OPENSSL_CTX *libctx, const char *propq);
PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(const EVP_PKEY *pkey);
int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
diff --git a/providers/implementations/encode_decode/decode_common.c b/providers/implementations/encode_decode/decode_common.c
index 2277c150c1..798d8f10b2 100644
--- a/providers/implementations/encode_decode/decode_common.c
+++ b/providers/implementations/encode_decode/decode_common.c
@@ -15,7 +15,7 @@
#include <openssl/pkcs12.h>
#include "internal/pem.h" /* For internal PVK and "blob" functions */
#include "internal/cryptlib.h"
-#include "crypto/asn1.h"
+#include "internal/asn1.h"
#include "internal/passphrase.h"
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 96f834500d..a12d527267 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5286,3 +5286,11 @@ OSSL_PARAM_get_octet_string_ptr ? 3_0_0 EXIST::FUNCTION:
OSSL_DECODER_CTX_set_passphrase_cb ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_set_mac_key ? 3_0_0 EXIST::FUNCTION:
EVP_PKEY_new_CMAC_key_with_libctx ? 3_0_0 EXIST::FUNCTION:
+OSSL_STORE_INFO_new ? 3_0_0 EXIST::FUNCTION:
+OSSL_STORE_INFO_get0_data ? 3_0_0 EXIST::FUNCTION:
+ossl_do_blob_header ? 3_0_0 EXIST::FUNCTION:DSA
+ossl_do_PVK_header ? 3_0_0 EXIST::FUNCTION:DSA,RC4
+asn1_d2i_read_bio ? 3_0_0 EXIST::FUNCTION:
+EVP_PKCS82PKEY_with_libctx ? 3_0_0 EXIST::FUNCTION:
+ossl_b2i ? 3_0_0 EXIST::FUNCTION:DSA
+ossl_b2i_bio ? 3_0_0 EXIST::FUNCTION:DSA
diff --git a/util/missingcrypto-internal.txt b/util/missingcrypto-internal.txt
index 4c90857035..54e1bc9ba7 100644
--- a/util/missingcrypto-internal.txt
+++ b/util/missingcrypto-internal.txt
@@ -1,3 +1,8 @@
WPACKET(3)
WPACKET_init_der(3)
WPACKET_init_null_der(3)
+asn1_d2i_read_bio(3)
+ossl_do_PVK_header(3)
+ossl_do_blob_header(3)
+ossl_b2i(3)
+ossl_b2i_bio(3)
diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt
index 54ff9cc1b7..783df1203f 100644
--- a/util/missingcrypto.txt
+++ b/util/missingcrypto.txt
@@ -673,6 +673,7 @@ EVP_PBE_find(3)
EVP_PBE_get(3)
EVP_PBE_scrypt(3)
EVP_PKCS82PKEY(3)
+EVP_PKCS82PKEY_with_libctx(3)
EVP_PKEY2PKCS8(3)
EVP_PKEY_CTX_get0_peerkey(3)
EVP_PKEY_CTX_get0_pkey(3)