When a property query string was used, it was not being applied to decoders.
When multiple providers supporting the same algorithm were loaded, it was
undefined which provider would be used when decoding a key, even when a
propquery string was provided. This fix scores decoder instances based on
property query matching and selects the highest scored decoder instance when
building the decoder chain.
The fake_rsa test provider is updated to support basic encoding and decoding.
A test is added using the fake_rsa provider to ensure that property query
strings are respected when loading decoders.
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27876)
- The decoder should consider fewer options based on
more precise tracking of the desired input type
(DER, PVK, MSBLOB), algorithm (RSA, EC, ...),
input structure (SPKI, P8, ...).
How much this affects actual use-cases is harder to estimate, we'll just
have to run before/after perf tests.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26927)
The decoders in some cases failed to capture or propagate
information about what is being decoded, causing more work
happen to try unrelated decoders as a fallback.
We now try harder to keep track of the expected object (private key or
public key, if known), and the algorithm determined from the OID of a
PKCS8 object or SPKI. This leads in many cases to fewer decoder
invocations. With so many more algorithms now, trying every decoder
is increasingly best avoided.
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26892)
- Also added a provider "validate" method that wraps the PCT test.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26656)
We're always supposed to add the fallback "unsupported" error if we don't
have anything better. However in some cases this wasn't happening because
we were incorrectly setting "flag_construct_called" - even though the
construct function had failed.
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21603)
The most expensive part of using a PKEY decoder is the
OSSL_DECODER_CTX_new_for_pkey() call. This builds up all of the decoder
chains, which is a complex and time consuming operation. However, if no
new providers have been loaded/unloaded since the last time it was called
we can expect the same results for the same parameters. Note that this
operation takes place *before* we event parse the data for decoding so it
is not dependent on the parsed data at all.
We introduce a cache for OSSL_DECODER_CTX objects. If we have been called
with the same parameters then we just duplicate an existing
OSSL_DECODER_CTX. This should be significantly faster than creating a new
one every time.
Partially addressed the issue in #15199
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21426)
Since OPENSSL_malloc() and friends report ERR_R_MALLOC_FAILURE, and
at least handle the file name and line number they are called from,
there's no need to report ERR_R_MALLOC_FAILURE where they are called
directly, or when SSLfatal() and RLAYERfatal() is used, the reason
`ERR_R_MALLOC_FAILURE` is changed to `ERR_R_CRYPTO_LIB`.
There were a number of places where `ERR_R_MALLOC_FAILURE` was reported
even though it was a function from a different sub-system that was
called. Those places are changed to report ERR_R_{lib}_LIB, where
{lib} is the name of that sub-system.
Some of them are tricky to get right, as we have a lot of functions
that belong in the ASN1 sub-system, and all the `sk_` calls or from
the CRYPTO sub-system.
Some extra adaptation was necessary where there were custom OPENSSL_malloc()
wrappers, and some bugs are fixed alongside these changes.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/19301)
This refactors decoder functionality to reduce calls to
OSSL_DECODER_is_a / EVP_KEYMGMT_is_a, which are substantial bottlenecks
in the performance of repeated decode operations (see #15199).
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17921)
Including e_os.h with a path from a header file doesn't work well on
certain exotic platform. It simply fails to build.
Since we don't seem to be able to stop ourselves, the better move is
to move e_os.h to an include directory that's part of the inclusion
path given to the compiler.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17641)
In a chain of decoders, the first that specifies an input structure
gets it compared with the structure specified by the user, if there is
one. If they aren't the same, that decoder is skipped.
Because the first structure can appear anywhere along a chain of
decoders, not just the decoders associated with the resulting OpenSSL
type, the code that checked the structure name when building up the
chain of decoders is removed.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/16466)
If there are any new errors reported we avoid raising the
OSSL_DECODER_from_bio:unsupported error.
Fixes#14566
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15878)
OSSL_DECODER_CTX_add_extra was calling OSSL_DECODER_do_all_provided in a
loop which was resulting in a large number of calls. Since
OSSL_DECODER_do_all_provided is quite "heavy" this was causing performance
issues.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15716)
Now that we have functions to get the name and properties of the
diverse implementations, we can as well display them for clarity.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15498)
The new PKCS#8 decoder implementation decodes from DER to DER.
OSSL_DECODER_CTX_add_extra() wasn't suited for this case; we had to
modify it to walk through all existing decoder implementations, and
filter out those that aren't suitable.
This also turns out to fix the possibility to have more than one extra
decoder implementation that produces the same type of encoding, for
example several different wrapper formats that all decoder into DER.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15498)
The OSSL_DECODER library used to ask each decoder implementation for
certain data in form of parameters to place them correctly in the
decoder chain, if at all. These parameters were duplicates of
properties of those same implementations, and therefore unnecessarily
redundant.
Now that we have functionality to query property definition values,
those duplicates are no longer needed, and are therefore not looked at
any more.
This adds the "global" error reason ERR_R_INVALID_PROPERTY_DEFINITION,
which can be re-used elsewhere.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15570)
For functions that exist in 1.1.1 provide a simple aliases via #define.
Fixes#15236
Functions with OSSL_DECODER_, OSSL_ENCODER_, OSSL_STORE_LOADER_,
EVP_KEYEXCH_, EVP_KEM_, EVP_ASYM_CIPHER_, EVP_SIGNATURE_,
EVP_KEYMGMT_, EVP_RAND_, EVP_MAC_, EVP_KDF_, EVP_PKEY_,
EVP_MD_, and EVP_CIPHER_ prefixes are renamed.
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15405)
If you don't have the base or default providers loaded and therefore there
are no encoders/decoders or store loaders then the error messages can be
cryptic. We provide better hints about how to fix the problem.
Fixes#13798
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15306)
So far, decoder implementations would return true (1) for a successful
decode all the way, including what the callback it called returned,
and false (0) in all other cases.
This construction didn't allow to stop to decoding process on fatal
errors, nor to choose what to report in the provider code.
This is now changed so that decoders implementations are made to
return false only on errors that should stop the decoding process from
carrying on with other implementations, and return true for all other
cases, even if that didn't result in a constructed object (EVP_PKEY
for example), essentially making it OK to return "empty handed".
The success of the decoding process is now all about successfully
constructing the final object, rather than about the return value of
the decoding chain. If no construction is attempted, the central
decoding processing code concludes that whatever the input consisted
of, it's not supported by the available decoder implementations.
Fixes#14423
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14834)
Providers (particularly the FIPS provider) needs access to BIOs from libcrypto.
Libcrypto is allowed to change the internal format of the BIO structure and it
is still expected to work with providers that were already built. This means
that the libcrypto BIO must be distinct from and not castable to the provider
side OSSL_CORE_BIO.
Unfortunately, this requirement was broken in both directions. This fixes
things by forcing the two to be different and any casts break loudly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14419)
Fixes#13185Fixes#13352
Removed the existing code in file_store that was trying to figure out the
input type.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14407)
Any decoder can now also declare the name of the data structure for
the object it decoded in the OSSL_PARAM array they pass back to the
decoding process. The decoding process will use that as another
criterion to select the next decoder in the chain to consider.
Together with declaring the data type, this becomes a means to refine
how the decoded data is treated along the chain.
Fixes#13539
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14233)
Many of the new types introduced by OpenSSL 3.0 have an OSSL_ prefix,
e.g., OSSL_CALLBACK, OSSL_PARAM, OSSL_ALGORITHM, OSSL_SERIALIZER.
The OPENSSL_CTX type stands out a little by using a different prefix.
For consistency reasons, this type is renamed to OSSL_LIB_CTX.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12621)
This adds OSSL_ENCODER_to_data() and OSSL_DECODER_from_data(). These
functions allow fairly simple rewrites of type-specific i2d and d2i
calls.
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13094)
If an explicit decoder start type was provided then it wasn't being
handled correctly in all cases. Specifically if a PEM start type was
provided then the decoder would fail.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/13050)
The PEM->DER decoder passes the data type of its contents, something
that decoder_process() ignored.
On the other hand, the PEM->DER decoder passed nonsense.
Both issues are fixed here.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13060)
Also adds error output tests on loading key files with unsupported algorithms to 30-test_evp.t
Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13023)
Mostly source nits, but also removing a couple of OSSL_DECODER_PARAM
macros that are never used or even make sense.
Also, some function names weren't quite consistent. They were made a
bit more consistent in the OSSL_ENCODER API, now we bring that back to
OSSL_DECODER.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12873)
This replaces the older 'file:' loader that is now an engine.
It's still possible to use the older 'file:' loader by explicitly
using the engine, and tests will remain for it as long as ENGINEs are
still supported (even through deprecated).
To support this storemgmt implementation, a few internal OSSL_DECODER
modifications are needed:
- An internal function that implements most of
OSSL_DECODER_CTX_new_by_EVP_PKEY(), but operates on an already
existing OSSL_DECODER_CTX instead of allocating a new one.
- Allow direct creation of a OSSL_DECODER from an OSSL_ALGORITHM.
It isn't attached to any provider, and is only used internally, to
simply catch any DER encoded object to be passed back to the
object callback with no further checking. This implementation
becomes the last resort decoder, when all "normal"
decodation attempts (i.e. those that are supposed to result
in an OpenSSL object of some sort) have failed.
Because file_store_attach() uses BIO_tell(), we must also support
BIO_ctrl() as a libcrypto upcall.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/12587)
The pass phrase prompter that's part of OSSL_ENCODER and OSSL_DECODER
is really a passphrase callback bridge between the diverse forms of
prompters that exist within OpenSSL: pem_password_cb, ui_method and
OSSL_PASSPHRASE_CALLBACK.
This can be generalised, to be re-used by other parts of OpenSSL, and
to thereby allow the users to specify whatever form of pass phrase
callback they need, while being able to pass that on to other APIs
that are called internally, in the form that those APIs demand.
Additionally, we throw in the possibility to cache pass phrases during
a "session" (we leave it to each API to define what a "session" is).
This is useful for any API that implements discovery and therefore may
need to get the same password more than once, such as OSSL_DECODER and
OSSL_STORE.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12512)
This is placed as CORE because the core of libcrypto is the authority
for what is possible to do and what's required to make these abstract
objects work.
In essence, an abstract object is an OSSL_PARAM array with well
defined parameter keys and values:
- an object type, which is a number indicating what kind of
libcrypto structure the object in question can be used with. The
currently possible numbers are defined in <openssl/core_object.h>.
- an object data type, which is a string that indicates more closely
what the contents of the object are.
- the object data, an octet string. The exact encoding used depends
on the context in which it's used. For example, the decoder
sub-system accepts any encoding, as long as there is a decoder
implementation that takes that as input. If central code is to
handle the data directly, DER encoding is assumed. (*)
- an object reference, also an octet string. This octet string is
not the object contents, just a mere reference to a provider-native
object. (**)
- an object description, which is a human readable text string that
can be displayed if some software desires to do so.
The intent is that certain provider-native operations (called X
here) are able to return any sort of object that belong with other
operations, or an object that has no provider support otherwise.
(*) A future extension might be to be able to specify encoding.
(**) The possible mechanisms for dealing with object references are:
- An object loading function in the target operation. The exact
target operation is determined by the object type (for example,
OSSL_OBJECT_PKEY implies that the target operation is a KEYMGMT)
and the implementation to be fetched by its object data type (for
an OSSL_OBJECT_PKEY, that's the KEYMGMT keytype to be fetched).
This loading function is only useful for this if the implementations
that are involved (X and KEYMGMT, for example) are from the same
provider.
- An object exporter function in the operation X implementation.
That exporter function can be used to export the object data in
OSSL_PARAM form that can be imported by a target operation's
import function. This can be used when it's not possible to fetch
the target operation implementation from the same provider.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12512)