diff options
-rw-r--r-- | crypto/encode_decode/decoder_lib.c | 85 | ||||
-rw-r--r-- | crypto/encode_decode/decoder_meth.c | 15 | ||||
-rw-r--r-- | crypto/encode_decode/decoder_pkey.c | 41 | ||||
-rw-r--r-- | crypto/err/openssl.txt | 4 | ||||
-rw-r--r-- | crypto/provider_core.c | 1 | ||||
-rw-r--r-- | include/crypto/decoder.h | 40 | ||||
-rw-r--r-- | include/openssl/core_dispatch.h | 3 | ||||
-rw-r--r-- | include/openssl/err.h | 5 | ||||
-rw-r--r-- | providers/baseprov.c | 11 | ||||
-rw-r--r-- | providers/common/bio_prov.c | 16 | ||||
-rw-r--r-- | providers/common/include/prov/bio.h | 1 | ||||
-rw-r--r-- | providers/common/include/prov/providercommonerr.h | 3 | ||||
-rw-r--r-- | providers/common/provider_err.c | 6 | ||||
-rw-r--r-- | providers/defltprov.c | 11 | ||||
-rw-r--r-- | providers/implementations/build.info | 2 | ||||
-rw-r--r-- | providers/implementations/include/prov/implementations.h | 2 | ||||
-rw-r--r-- | providers/implementations/storemgmt/build.info | 6 | ||||
-rw-r--r-- | providers/implementations/storemgmt/file_store.c | 920 | ||||
-rw-r--r-- | providers/implementations/storemgmt/file_store_der2obj.c | 119 | ||||
-rw-r--r-- | providers/implementations/storemgmt/file_store_local.h | 11 | ||||
-rw-r--r-- | providers/stores.inc | 14 |
21 files changed, 1266 insertions, 50 deletions
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index 17dca0fc22..9eeff20f7c 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -12,6 +12,7 @@ #include <openssl/params.h> #include <openssl/provider.h> #include "internal/passphrase.h" +#include "crypto/decoder.h" #include "encoder_local.h" #include "e_os.h" @@ -89,14 +90,13 @@ int OSSL_DECODER_CTX_set_input_type(OSSL_DECODER_CTX *ctx, return 1; } -int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) +OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, + void *decoderctx) { OSSL_DECODER_INSTANCE *decoder_inst = NULL; - const OSSL_PROVIDER *prov = NULL; OSSL_PARAM params[2]; - void *provctx = NULL; - if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) { + if (!ossl_assert(decoder != NULL)) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); return 0; } @@ -107,12 +107,6 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) return 0; } - if (ctx->decoder_insts == NULL - && (ctx->decoder_insts = - sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) { - ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); - return 0; - } if ((decoder_inst = OPENSSL_zalloc(sizeof(*decoder_inst))) == NULL) { ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); return 0; @@ -121,10 +115,6 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR); goto err; } - decoder_inst->decoder = decoder; - - prov = OSSL_DECODER_provider(decoder_inst->decoder); - provctx = OSSL_PROVIDER_get0_provider_ctx(prov); /* Cache the input type for this encoder */ params[0] = @@ -132,25 +122,74 @@ int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, OSSL_DECODER *decoder) (char **)&decoder_inst->input_type, 0); params[1] = OSSL_PARAM_construct_end(); - if (!decoder_inst->decoder->get_params(params) + if (!decoder->get_params(params) || !OSSL_PARAM_modified(¶ms[0])) goto err; - if ((decoder_inst->decoderctx = decoder_inst->decoder->newctx(provctx)) - == NULL) - goto err; - - if (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, decoder_inst) <= 0) - goto err; - - return 1; + decoder_inst->decoder = decoder; + decoder_inst->decoderctx = decoderctx; + return decoder_inst; err: + ossl_decoder_instance_free(decoder_inst); + return NULL; +} + +void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst) +{ if (decoder_inst != NULL) { if (decoder_inst->decoder != NULL) decoder_inst->decoder->freectx(decoder_inst->decoderctx); + decoder_inst->decoderctx = NULL; OSSL_DECODER_free(decoder_inst->decoder); + decoder_inst->decoder = NULL; OPENSSL_free(decoder_inst); } +} + +int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_INSTANCE *di) +{ + if (ctx->decoder_insts == NULL + && (ctx->decoder_insts = + sk_OSSL_DECODER_INSTANCE_new_null()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return 0; + } + + return (sk_OSSL_DECODER_INSTANCE_push(ctx->decoder_insts, di) > 0); +} + +int OSSL_DECODER_CTX_add_decoder(OSSL_DECODER_CTX *ctx, + OSSL_DECODER *decoder) +{ + OSSL_DECODER_INSTANCE *decoder_inst = NULL; + const OSSL_PROVIDER *prov = NULL; + void *decoderctx = NULL; + void *provctx = NULL; + + if (!ossl_assert(ctx != NULL) || !ossl_assert(decoder != NULL)) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + prov = OSSL_DECODER_provider(decoder); + provctx = OSSL_PROVIDER_get0_provider_ctx(prov); + + if ((decoderctx = decoder->newctx(provctx)) == NULL + || (decoder_inst = + ossl_decoder_instance_new(decoder, decoderctx)) == NULL) + goto err; + /* Avoid double free of decoderctx on further errors */ + decoderctx = NULL; + + if (!ossl_decoder_ctx_add_decoder_inst(ctx, decoder_inst)) + goto err; + + return 1; + err: + ossl_decoder_instance_free(decoder_inst); + if (decoderctx != NULL) + decoder->freectx(decoderctx); return 0; } diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c index 21cd53e32b..235899b6ce 100644 --- a/crypto/encode_decode/decoder_meth.c +++ b/crypto/encode_decode/decoder_meth.c @@ -15,11 +15,9 @@ #include "internal/namemap.h" #include "internal/property.h" #include "internal/provider.h" -#include "crypto/encoder.h" +#include "crypto/decoder.h" #include "encoder_local.h" -static void OSSL_DECODER_INSTANCE_free(OSSL_DECODER_INSTANCE *instance); - /* * Decoder can have multiple names, separated with colons in a name string */ @@ -159,8 +157,8 @@ static int put_decoder_in_store(OPENSSL_CTX *libctx, void *store, } /* Create and populate a decoder method */ -static void *decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef, - OSSL_PROVIDER *prov) +void *ossl_decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov) { OSSL_DECODER *decoder = NULL; const OSSL_DISPATCH *fns = algodef->implementation; @@ -236,7 +234,7 @@ static void *decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef, /* * The core fetching functionality passes the names of the implementation. * This function is responsible to getting an identity number for them, - * then call decoder_from_dispatch() with that identity number. + * then call ossl_decoder_from_dispatch() with that identity number. */ static void *construct_decoder(const OSSL_ALGORITHM *algodef, OSSL_PROVIDER *prov, void *unused) @@ -254,7 +252,7 @@ static void *construct_decoder(const OSSL_ALGORITHM *algodef, void *method = NULL; if (id != 0) - method = decoder_from_dispatch(id, algodef, prov); + method = ossl_decoder_from_dispatch(id, algodef, prov); return method; } @@ -407,8 +405,7 @@ static void decoder_do_one(OSSL_PROVIDER *provider, void *method = NULL; if (id != 0) - method = - decoder_from_dispatch(id, algodef, provider); + method = ossl_decoder_from_dispatch(id, algodef, provider); if (method != NULL) { data->user_fn(method, data->user_arg); diff --git a/crypto/encode_decode/decoder_pkey.c b/crypto/encode_decode/decoder_pkey.c index 11b087203b..64ea4e2c3f 100644 --- a/crypto/encode_decode/decoder_pkey.c +++ b/crypto/encode_decode/decoder_pkey.c @@ -14,6 +14,7 @@ #include <openssl/decoder.h> #include <openssl/safestack.h> #include "crypto/evp.h" +#include "crypto/decoder.h" #include "encoder_local.h" int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, @@ -254,17 +255,16 @@ static void collect_decoder(OSSL_DECODER *decoder, void *arg) data->error_occured = 0; /* All is good now */ } -OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, - const char *input_type, - OPENSSL_CTX *libctx, - const char *propquery) +int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, + EVP_PKEY **pkey, + OPENSSL_CTX *libctx, + const char *propquery) { - OSSL_DECODER_CTX *ctx = NULL; struct collected_data_st *data = NULL; size_t i, end_i; + int ok = 0; - if ((ctx = OSSL_DECODER_CTX_new()) == NULL - || (data = OPENSSL_zalloc(sizeof(*data))) == NULL + if ((data = OPENSSL_zalloc(sizeof(*data))) == NULL || (data->process_data = OPENSSL_zalloc(sizeof(*data->process_data))) == NULL || (data->process_data->keymgmts @@ -275,7 +275,6 @@ OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, } data->process_data->object = (void **)pkey; data->ctx = ctx; - OSSL_DECODER_CTX_set_input_type(ctx, input_type); /* First, find all keymgmts to form goals */ EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, data); @@ -308,9 +307,6 @@ OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, if (OSSL_DECODER_CTX_num_decoders(ctx) == 0) goto err; - /* Finally, collect extra decoders based on what we already have */ - (void)OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery); - if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_EVP_PKEY) || !OSSL_DECODER_CTX_set_construct_data(ctx, data->process_data) || !OSSL_DECODER_CTX_set_cleanup(ctx, @@ -318,11 +314,32 @@ OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, goto err; data->process_data = NULL; + ok = 1; err: if (data != NULL) { decoder_clean_EVP_PKEY_construct_arg(data->process_data); sk_OPENSSL_CSTRING_free(data->names); OPENSSL_free(data); } - return ctx; + return ok; +} + +OSSL_DECODER_CTX *OSSL_DECODER_CTX_new_by_EVP_PKEY(EVP_PKEY **pkey, + const char *input_type, + OPENSSL_CTX *libctx, + const char *propquery) +{ + OSSL_DECODER_CTX *ctx = NULL; + + if ((ctx = OSSL_DECODER_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (OSSL_DECODER_CTX_set_input_type(ctx, input_type) + && ossl_decoder_ctx_setup_for_EVP_PKEY(ctx, pkey, libctx, propquery) + && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)) + return ctx; + + OSSL_DECODER_CTX_free(ctx); + return NULL; } diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 643bf6b278..592fb6b50a 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2936,12 +2936,15 @@ PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:178:\ PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small PROV_R_PARENT_LOCKING_NOT_ENABLED:182:parent locking not enabled PROV_R_PARENT_STRENGTH_TOO_WEAK:194:parent strength too weak +PROV_R_PATH_MUST_BE_ABSOLUTE:219:path must be absolute PROV_R_PERSONALISATION_STRING_TOO_LONG:195:personalisation string too long PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small PROV_R_READ_KEY:159:read key PROV_R_REQUEST_TOO_LARGE_FOR_DRBG:196:request too large for drbg PROV_R_REQUIRE_CTR_MODE_CIPHER:206:require ctr mode cipher PROV_R_RESEED_ERROR:197:reseed error +PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES:222:\ + search only supported for directories PROV_R_SELF_TEST_KAT_FAILURE:215:self test kat failure PROV_R_SELF_TEST_POST_FAILURE:216:self test post failure PROV_R_TAG_NOTSET:119:tag notset @@ -2963,6 +2966,7 @@ PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg PROV_R_UNSUPPORTED_KEY_SIZE:153:unsupported key size PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS:152:unsupported number of rounds +PROV_R_URI_AUTHORITY_UNSUPPORTED:223:uri authority unsupported PROV_R_VALUE_ERROR:138:value error PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length PROV_R_WRONG_OUTPUT_BUFFER_SIZE:139:wrong output buffer size diff --git a/crypto/provider_core.c b/crypto/provider_core.c index f282071e2d..754f6df1a4 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -1094,6 +1094,7 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_BIO_WRITE_EX, (void (*)(void))BIO_write_ex }, { OSSL_FUNC_BIO_GETS, (void (*)(void))BIO_gets }, { OSSL_FUNC_BIO_PUTS, (void (*)(void))BIO_puts }, + { OSSL_FUNC_BIO_CTRL, (void (*)(void))BIO_ctrl }, { OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free }, { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf }, { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf }, diff --git a/include/crypto/decoder.h b/include/crypto/decoder.h new file mode 100644 index 0000000000..b465752971 --- /dev/null +++ b/include/crypto/decoder.h @@ -0,0 +1,40 @@ +/* + * 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_CRYPTO_DECODER_H +# define OSSL_CRYPTO_DECODER_H + +# include <openssl/decoder.h> + +OSSL_DECODER *ossl_decoder_fetch_by_number(OPENSSL_CTX *libctx, + int id, + const char *properties); + +/* + * These are specially made for the 'file:' provider-native loader, which + * uses this to install a DER to anything decoder, which doesn't do much + * except read a DER blob and pass it on as a provider object abstraction + * (provider-object(7)). + */ +void *ossl_decoder_from_dispatch(int id, const OSSL_ALGORITHM *algodef, + OSSL_PROVIDER *prov); + +OSSL_DECODER_INSTANCE * +ossl_decoder_instance_new(OSSL_DECODER *decoder, void *decoderctx); +void ossl_decoder_instance_free(OSSL_DECODER_INSTANCE *decoder_inst); +int ossl_decoder_ctx_add_decoder_inst(OSSL_DECODER_CTX *ctx, + OSSL_DECODER_INSTANCE *di); + +int ossl_decoder_ctx_setup_for_EVP_PKEY(OSSL_DECODER_CTX *ctx, + EVP_PKEY **pkey, + OPENSSL_CTX *libctx, + const char *propquery); + +#endif + diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index b21fe559f7..ac83f88cc4 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -137,6 +137,7 @@ OSSL_CORE_MAKE_FUNC(void, #define OSSL_FUNC_BIO_VSNPRINTF 46 #define OSSL_FUNC_BIO_PUTS 47 #define OSSL_FUNC_BIO_GETS 48 +#define OSSL_FUNC_BIO_CTRL 49 OSSL_CORE_MAKE_FUNC(OSSL_CORE_BIO *, BIO_new_file, (const char *filename, @@ -153,6 +154,8 @@ OSSL_CORE_MAKE_FUNC(int, BIO_vprintf, (OSSL_CORE_BIO *bio, const char *format, va_list args)) OSSL_CORE_MAKE_FUNC(int, BIO_vsnprintf, (char *buf, size_t n, const char *fmt, va_list args)) +OSSL_CORE_MAKE_FUNC(int, BIO_ctrl, (OSSL_CORE_BIO *bio, + int cmd, long num, void *ptr)) #define OSSL_FUNC_SELF_TEST_CB 100 OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb, diff --git a/include/openssl/err.h b/include/openssl/err.h index 497436d2c5..3e3b64b158 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -113,8 +113,8 @@ struct err_state_st { # define ERR_LIB_CRMF 56 # define ERR_LIB_PROV 57 # define ERR_LIB_CMP 58 -# define ERR_LIB_OSSL_ENCODER 59 -# define ERR_LIB_OSSL_DECODER 60 +# define ERR_LIB_OSSL_ENCODER 59 +# define ERR_LIB_OSSL_DECODER 60 # define ERR_LIB_HTTP 61 # define ERR_LIB_USER 128 @@ -304,6 +304,7 @@ static ossl_inline int ERR_FATAL_ERROR(unsigned long errcode) # define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ # define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ # define ERR_R_OSSL_STORE_LIB ERR_LIB_OSSL_STORE/* 44 */ +# define ERR_R_OSSL_DECODER_LIB ERR_LIB_OSSL_DECODER/* 60 */ /* * global reason codes, range 64..99 (sub-system specific codes start at 100) diff --git a/providers/baseprov.c b/providers/baseprov.c index dcea2ad93e..38d9090bb3 100644 --- a/providers/baseprov.c +++ b/providers/baseprov.c @@ -86,6 +86,15 @@ static const OSSL_ALGORITHM base_decoder[] = { }; #undef DECODER +static const OSSL_ALGORITHM base_store[] = { +#define STORE(name, fips, func_table) \ + { name, "provider=base,fips=" fips, (func_table) }, + +#include "stores.inc" + { NULL, NULL, NULL } +#undef STORE +}; + static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, int *no_cache) { @@ -95,6 +104,8 @@ static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, return base_encoder; case OSSL_OP_DECODER: return base_decoder; + case OSSL_OP_STORE: + return base_store; } return NULL; } diff --git a/providers/common/bio_prov.c b/providers/common/bio_prov.c index fc1f8b2b26..c049795cd1 100644 --- a/providers/common/bio_prov.c +++ b/providers/common/bio_prov.c @@ -18,6 +18,7 @@ static OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex = NULL; static OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex = NULL; static OSSL_FUNC_BIO_gets_fn *c_bio_gets = NULL; static OSSL_FUNC_BIO_puts_fn *c_bio_puts = NULL; +static OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl = NULL; static OSSL_FUNC_BIO_free_fn *c_bio_free = NULL; static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf = NULL; @@ -49,6 +50,10 @@ int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) if (c_bio_puts == NULL) c_bio_puts = OSSL_FUNC_BIO_puts(fns); break; + case OSSL_FUNC_BIO_CTRL: + if (c_bio_ctrl == NULL) + c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns); + break; case OSSL_FUNC_BIO_FREE: if (c_bio_free == NULL) c_bio_free = OSSL_FUNC_BIO_free(fns); @@ -107,6 +112,13 @@ int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str) return c_bio_puts(bio, str); } +int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr) +{ + if (c_bio_ctrl == NULL) + return -1; + return c_bio_ctrl(bio, cmd, num, ptr); +} + int ossl_prov_bio_free(OSSL_CORE_BIO *bio) { if (c_bio_free == NULL) @@ -151,9 +163,7 @@ static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len, static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr) { - /* We don't support this */ - assert(0); - return 0; + return ossl_prov_bio_ctrl(BIO_get_data(bio), cmd, num, ptr); } static int bio_core_gets(BIO *bio, char *buf, int size) diff --git a/providers/common/include/prov/bio.h b/providers/common/include/prov/bio.h index 3cef89ce18..9dd9f44bad 100644 --- a/providers/common/include/prov/bio.h +++ b/providers/common/include/prov/bio.h @@ -22,6 +22,7 @@ int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len size_t *written); int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size); int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str); +int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr); int ossl_prov_bio_free(OSSL_CORE_BIO *bio); int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap); int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...); diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index 4c356fc5c6..82eea21049 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -139,12 +139,14 @@ int ERR_load_PROV_strings(void); # define PROV_R_OUTPUT_BUFFER_TOO_SMALL 106 # define PROV_R_PARENT_LOCKING_NOT_ENABLED 182 # define PROV_R_PARENT_STRENGTH_TOO_WEAK 194 +# define PROV_R_PATH_MUST_BE_ABSOLUTE 219 # define PROV_R_PERSONALISATION_STRING_TOO_LONG 195 # define PROV_R_PSS_SALTLEN_TOO_SMALL 172 # define PROV_R_READ_KEY 159 # define PROV_R_REQUEST_TOO_LARGE_FOR_DRBG 196 # define PROV_R_REQUIRE_CTR_MODE_CIPHER 206 # define PROV_R_RESEED_ERROR 197 +# define PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 222 # define PROV_R_SELF_TEST_KAT_FAILURE 215 # define PROV_R_SELF_TEST_POST_FAILURE 216 # define PROV_R_TAG_NOTSET 119 @@ -165,6 +167,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_UNSUPPORTED_KEY_SIZE 153 # define PROV_R_UNSUPPORTED_MAC_TYPE 137 # define PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS 152 +# define PROV_R_URI_AUTHORITY_UNSUPPORTED 223 # define PROV_R_VALUE_ERROR 138 # define PROV_R_WRONG_FINAL_BLOCK_LENGTH 107 # define PROV_R_WRONG_OUTPUT_BUFFER_SIZE 139 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 3ea41f3c25..6d6a254dd6 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -149,6 +149,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "parent locking not enabled"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_STRENGTH_TOO_WEAK), "parent strength too weak"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PATH_MUST_BE_ABSOLUTE), + "path must be absolute"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PERSONALISATION_STRING_TOO_LONG), "personalisation string too long"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PSS_SALTLEN_TOO_SMALL), @@ -159,6 +161,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REQUIRE_CTR_MODE_CIPHER), "require ctr mode cipher"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_RESEED_ERROR), "reseed error"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES), + "search only supported for directories"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_KAT_FAILURE), "self test kat failure"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_POST_FAILURE), @@ -196,6 +200,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "unsupported mac type"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS), "unsupported number of rounds"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_URI_AUTHORITY_UNSUPPORTED), + "uri authority unsupported"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_VALUE_ERROR), "value error"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"}, diff --git a/providers/defltprov.c b/providers/defltprov.c index 855497be06..beaf60bb1e 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -433,6 +433,15 @@ static const OSSL_ALGORITHM deflt_decoder[] = { }; #undef DECODER +static const OSSL_ALGORITHM deflt_store[] = { +#define STORE(name, fips, func_table) \ + { name, "provider=default,fips=" fips, (func_table) }, + +#include "stores.inc" + { NULL, NULL, NULL } +#undef STORE +}; + static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id, int *no_cache) { @@ -461,6 +470,8 @@ static const OSSL_ALGORITHM *deflt_query(void *provctx, int operation_id, return deflt_encoder; case OSSL_OP_DECODER: return deflt_decoder; + case OSSL_OP_STORE: + return deflt_store; } return NULL; } diff --git a/providers/implementations/build.info b/providers/implementations/build.info index 54392cf68b..fe67e59401 100644 --- a/providers/implementations/build.info +++ b/providers/implementations/build.info @@ -1,2 +1,2 @@ SUBDIRS=digests ciphers rands macs kdfs exchange keymgmt signature asymciphers \ - encode_decode + encode_decode storemgmt diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index 1b8642415f..7060a4b839 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -385,3 +385,5 @@ extern const OSSL_DISPATCH der_to_rsapss_decoder_functions[]; extern const OSSL_DISPATCH msblob_to_rsa_decoder_functions[]; extern const OSSL_DISPATCH pvk_to_rsa_decoder_functions[]; extern const OSSL_DISPATCH pem_to_der_decoder_functions[]; + +extern const OSSL_DISPATCH file_store_functions[]; diff --git a/providers/implementations/storemgmt/build.info b/providers/implementations/storemgmt/build.info new file mode 100644 index 0000000000..89939cce54 --- /dev/null +++ b/providers/implementations/storemgmt/build.info @@ -0,0 +1,6 @@ +# We make separate GOAL variables for each algorithm, to make it easy to +# switch each to the Legacy provider when needed. + +$STORE_GOAL=../../libimplementations.a + +SOURCE[$STORE_GOAL]=file_store.c file_store_der2obj.c diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c new file mode 100644 index 0000000000..70dbac600b --- /dev/null +++ b/providers/implementations/storemgmt/file_store.c @@ -0,0 +1,920 @@ +/* + * 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 + */ + +#include "e_os.h" /* To get strncasecmp() on Windows */ +#include <string.h> +#include <sys/stat.h> +#include <ctype.h> +#include <assert.h> + +#include <openssl/core.h> +#include <openssl/core_dispatch.h> +#include <openssl/core_names.h> +#include <openssl/core_object.h> +#include <openssl/crypto.h> +#include <openssl/bio.h> +#include <openssl/err.h> +#include <openssl/buffer.h> +#include <openssl/params.h> +#include <openssl/decoder.h> +#include <openssl/store.h> /* The OSSL_STORE_INFO type numbers */ +#include "internal/o_dir.h" +#include "internal/pem.h" /* For PVK and "blob" PEM headers */ +#include "crypto/decoder.h" +#include "prov/implementations.h" +#include "prov/bio.h" +#include "prov/provider_ctx.h" +#include "prov/providercommonerr.h" +#include "file_store_local.h" + +DEFINE_STACK_OF(X509) +DEFINE_STACK_OF(OSSL_STORE_INFO) + +#ifdef _WIN32 +# define stat _stat +#endif + +#ifndef S_ISDIR +# define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) +#endif + +static OSSL_FUNC_store_open_fn file_open; +static OSSL_FUNC_store_attach_fn file_attach; +static OSSL_FUNC_store_settable_ctx_params_fn file_settable_ctx_params; +static OSSL_FUNC_store_set_ctx_params_fn file_set_ctx_params; +static OSSL_FUNC_store_load_fn file_load; +static OSSL_FUNC_store_eof_fn file_eof; +static OSSL_FUNC_store_close_fn file_close; + +/* + * This implementation makes full use of OSSL_DECODER, and then some. + * It uses its own internal decoder implementation that reads DER and + * passes that on to the data callback; this decoder is created with + * internal OpenSSL functions, thereby bypassing the need for a surrounding + * provider. This is ok, since this is a local decoder, not meant for + * public consumption. It also uses the libcrypto internal decoder + * setup function ossl_decoder_ctx_setup_for_EVP_PKEY(), to allow the + * last resort decoder to be added first (and thereby be executed last). + * Finally, it sets up its own construct and cleanup functions. + * + * Essentially, that makes this implementation a kind of glorified decoder. + */ + +struct file_ctx_st { + void *provctx; + char *uri; /* The URI we currently try to load */ + enum { + IS_FILE = 0, /* Read file and pass results */ + IS_DIR /* Pass directory entry names */ + } type; + + /* Flag bits */ + unsigned int flag_attached:1; + unsigned int flag_buffered:1; + + union { + /* Used with |IS_FILE| */ + struct { + BIO *file; + + OSSL_DECODER_CTX *decoderctx; + char *input_type; + char *propq; /* The properties we got as a parameter */ + } file; + + /* Used with |IS_DIR| */ + struct { + OPENSSL_DIR_CTX *ctx; + int end_reached; + + /* + * When a search expression is given, these are filled in. + * |search_name| contains the file basename to look for. + * The string is exactly 8 characters long. + */ + char search_name[9]; + + /* + * The directory reading utility we have combines opening with + * reading the first name. To make sure we can detect the end + * at the right time, we read early and cache the name. + */ + const char *last_entry; + int last_errno; + } dir; + } _; + + /* Expected object type. May be unspecified */ + int expected_type; +}; + +static void free_file_ctx(struct file_ctx_st *ctx) +{ + if (ctx == NULL) + return; + + OPENSSL_free(ctx->uri); + if (ctx->type != IS_DIR) { + OSSL_DECODER_CTX_free(ctx->_.file.decoderctx); + OPENSSL_free(ctx->_.file.propq); + OPENSSL_free(ctx->_.file.input_type); + } + OPENSSL_free(ctx); +} |