Richard Levitte 7cfa1717b8 Modify providers that keep track of underlying algorithms
With some provider implementations, there are underlying ciphers,
digests and macs.  For some of them, the name was retrieved from the
method, but since the methods do not store those any more, we add
different mechanics.

For code that needs to pass on the name of a cipher or diges via
parameters, we simply locally store the name that was used when
fetching said cipher or digest.  This will ensure that any underlying
code that needs to fetch that same cipher or digest does so with the
exact same name instead of any random name from the set of names
associated with the algorithm.

For code that needs to check what kind of algorithm was passed, we
provide EVP_{type}_is_a(), that returns true if the given method has
the given name as one of its names.

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9897)
2019-09-19 14:58:17 +02:00

88 lines
3.3 KiB
C

/*
* Copyright 2019 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/provider.h>
#include <openssl/engine.h>
typedef struct {
/*
* References to the underlying cipher implementation. |cipher| caches
* the cipher, always. |alloc_cipher| only holds a reference to an
* explicitly fetched cipher.
*/
const EVP_CIPHER *cipher; /* cipher */
EVP_CIPHER *alloc_cipher; /* fetched cipher */
/* Conditions for legacy EVP_CIPHER uses */
ENGINE *engine; /* cipher engine */
/* Name this was fetched by */
char name[51]; /* A longer name would be unexpected */
} PROV_CIPHER;
typedef struct {
/*
* References to the underlying digest implementation. |md| caches
* the digest, always. |alloc_md| only holds a reference to an explicitly
* fetched digest.
*/
const EVP_MD *md; /* digest */
EVP_MD *alloc_md; /* fetched digest */
/* Conditions for legacy EVP_MD uses */
ENGINE *engine; /* digest engine */
/* Name this was fetched by */
char name[51]; /* A longer name would be unexpected */
} PROV_DIGEST;
/* Cipher functions */
/*
* Load a cipher from the specified parameters with the specified context.
* The params "properties", "engine" and "cipher" are used to determine the
* implementation used. If a provider cannot be found, it falls back to trying
* non-provider based implementations.
*/
int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
const OSSL_PARAM params[],
OPENSSL_CTX *ctx);
/* Reset the PROV_CIPHER fields and free any allocated cipher reference */
void ossl_prov_cipher_reset(PROV_CIPHER *pc);
/* Clone a PROV_CIPHER structure into a second */
int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src);
/* Query the cipher and associated engine (if any) */
const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc);
ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc);
const char *ossl_prov_cipher_name(const PROV_CIPHER *pc);
/* Digest functions */
/*
* Load a digest from the specified parameters with the specified context.
* The params "properties", "engine" and "digest" are used to determine the
* implementation used. If a provider cannot be found, it falls back to trying
* non-provider based implementations.
*/
int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
const OSSL_PARAM params[],
OPENSSL_CTX *ctx);
/* Reset the PROV_DIGEST fields and free any allocated digest reference */
void ossl_prov_digest_reset(PROV_DIGEST *pd);
/* Clone a PROV_DIGEST structure into a second */
int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src);
/* Query the digest and associated engine (if any) */
const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
const char *ossl_prov_digest_name(const PROV_DIGEST *pd);