diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index 441f83c345b05..ff4803be747d5 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 186e7ec4136e4..249e6294c8b3a 100644 --- a/crypto/asn1/a_d2i_fp.c +++ b/crypto/asn1/a_d2i_fp.c @@ -13,6 +13,7 @@ #include "internal/numbers.h" #include #include +#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 bd6ef1ce51256..f0217b47f607c 100644 --- a/crypto/asn1/d2i_param.c +++ b/crypto/asn1/d2i_param.c @@ -11,8 +11,9 @@ #include "internal/cryptlib.h" #include #include -#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 a4d240e7c4513..ba81782698802 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 cfe0544ed68f0..92ae3e5fe8fc7 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 33b59f0faeb4b..bd19237ba49d1 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 b87730736d2f5..4d434eb57bcbf 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 d0fdb38cd88bb..1c718c589e15f 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 619e547aaee89..cdd9f164b418d 100644 --- a/crypto/store/store_local.h +++ b/crypto/store/store_local.h @@ -28,11 +28,6 @@ struct ossl_store_info_st { union { 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; @@ -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 74aeaf543b70f..9df29cec0aa11 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 a8ad292074e0a..3e7dc42ef1476 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -23,7 +23,7 @@ #include #include #include -#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 bc965a77bdeb4..8c811ec1f31d2 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 with an arbitrary I +number and I structure. It's the responsibility of the caller to +define type numbers other than the ones defined by F<< >>, +and to handle freeing the associated data structure on their own. +I >> 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 matches the type number in I. + +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 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 -pointer on success, or B 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 3bfe1dc057242..4e83dbf9bcf32 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 similarity index 82% rename from crypto/store/loader_file.c rename to engines/e_loader_attic.c index 25ce9ba92e006..581bfb02853a6 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 #include #include @@ -21,25 +23,26 @@ #include #include #include -#include "internal/pem.h" #include /* For the PKCS8 stuff o.O */ #include /* For d2i_RSAPrivateKey */ #include #include #include +#include #include /* 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 0000000000000..525a689fe5821 --- /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 0000000000000..db1a996a339fa --- /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 0000000000000..2bc4e854c820b --- /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 +#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 0000000000000..115e0ea6f60e7 --- /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 +# include + + +# 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 041642f022a0a..624df3cb055e1 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 634eb86425976..b00634234c5ba 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 0000000000000..8448786919d04 --- /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 9a2b423371ae4..b2201cacaadfc 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 9aef28c954b36..d243fda94c409 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 2277c150c1ed7..798d8f10b2930 100644 --- a/providers/implementations/encode_decode/decode_common.c +++ b/providers/implementations/encode_decode/decode_common.c @@ -15,7 +15,7 @@ #include #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 96f834500d995..a12d5272677af 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 4c908570355fd..54e1bc9ba7dd0 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 54ff9cc1b7f01..783df1203f655 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)