2020-07-27 18:40:05 +02:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* low level APIs are deprecated for public use, but still ok for
|
|
|
|
* internal use.
|
|
|
|
*/
|
|
|
|
#include "internal/deprecated.h"
|
|
|
|
|
|
|
|
#include <openssl/core_dispatch.h>
|
|
|
|
#include <openssl/core_names.h>
|
CORE: Define provider-native abstract objects
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)
2020-07-22 15:34:25 +02:00
|
|
|
#include <openssl/core_object.h>
|
2020-07-27 18:40:05 +02:00
|
|
|
#include <openssl/crypto.h>
|
2020-09-07 12:25:17 +02:00
|
|
|
#include <openssl/err.h>
|
2020-07-27 18:40:05 +02:00
|
|
|
#include <openssl/params.h>
|
2020-09-07 12:25:17 +02:00
|
|
|
#include <openssl/pem.h> /* PEM_BUFSIZE and public PEM functions */
|
|
|
|
#include <openssl/pkcs12.h>
|
2020-07-27 18:40:05 +02:00
|
|
|
#include <openssl/x509.h>
|
2020-09-07 12:25:17 +02:00
|
|
|
#include "internal/cryptlib.h" /* ossl_assert() */
|
|
|
|
#include "internal/asn1.h"
|
|
|
|
#include "crypto/ecx.h"
|
2020-07-27 18:40:05 +02:00
|
|
|
#include "prov/bio.h"
|
|
|
|
#include "prov/implementations.h"
|
2020-09-07 12:25:17 +02:00
|
|
|
#include "prov/providercommonerr.h"
|
|
|
|
#include "endecoder_local.h"
|
2020-07-27 18:40:05 +02:00
|
|
|
|
2020-09-28 16:14:14 +02:00
|
|
|
#define SET_ERR_MARK() ERR_set_mark()
|
|
|
|
#define CLEAR_ERR_MARK() \
|
|
|
|
do { \
|
|
|
|
int err = ERR_peek_last_error(); \
|
|
|
|
\
|
|
|
|
if (ERR_GET_LIB(err) == ERR_LIB_ASN1 \
|
|
|
|
&& (ERR_GET_REASON(err) == ASN1_R_HEADER_TOO_LONG \
|
|
|
|
|| ERR_GET_REASON(err) == ASN1_R_UNSUPPORTED_TYPE \
|
|
|
|
|| ERR_GET_REASON(err) == ERR_R_NESTED_ASN1_ERROR)) \
|
|
|
|
ERR_pop_to_mark(); \
|
|
|
|
else \
|
|
|
|
ERR_clear_last_mark(); \
|
|
|
|
} while(0)
|
|
|
|
#define RESET_ERR_MARK() \
|
|
|
|
do { \
|
|
|
|
CLEAR_ERR_MARK(); \
|
|
|
|
SET_ERR_MARK(); \
|
|
|
|
} while(0)
|
|
|
|
|
2020-09-07 12:25:17 +02:00
|
|
|
static int read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
|
|
|
|
unsigned char **data, long *len)
|
|
|
|
{
|
|
|
|
BUF_MEM *mem = NULL;
|
|
|
|
BIO *in = bio_new_from_core_bio(provctx, cin);
|
|
|
|
int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
|
|
|
|
|
|
|
|
if (ok) {
|
|
|
|
*data = (unsigned char *)mem->data;
|
|
|
|
*len = (long)mem->length;
|
|
|
|
OPENSSL_free(mem);
|
|
|
|
}
|
|
|
|
BIO_free(in);
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int der_from_p8(unsigned char **new_der, long *new_der_len,
|
|
|
|
unsigned char *input_der, long input_der_len,
|
|
|
|
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
|
|
|
|
{
|
|
|
|
const unsigned char *derp;
|
|
|
|
X509_SIG *p8 = NULL;
|
|
|
|
int ok = 0;
|
|
|
|
|
|
|
|
if (!ossl_assert(new_der != NULL && *new_der == NULL)
|
|
|
|
|| !ossl_assert(new_der_len != NULL))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
derp = input_der;
|
|
|
|
if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) {
|
|
|
|
char pbuf[PEM_BUFSIZE];
|
|
|
|
size_t plen = 0;
|
|
|
|
|
|
|
|
if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
|
|
|
|
ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
|
|
|
|
} else {
|
|
|
|
const X509_ALGOR *alg = NULL;
|
|
|
|
const ASN1_OCTET_STRING *oct = NULL;
|
|
|
|
int len = 0;
|
|
|
|
|
|
|
|
X509_SIG_get0(p8, &alg, &oct);
|
|
|
|
if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length,
|
|
|
|
new_der, &len, 0) != NULL)
|
|
|
|
ok = 1;
|
|
|
|
*new_der_len = len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
X509_SIG_free(p8);
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ---------------------------------------------------------------------- */
|
2020-07-27 18:40:05 +02:00
|
|
|
|
2020-08-16 21:25:08 +02:00
|
|
|
static OSSL_FUNC_decoder_freectx_fn der2key_freectx;
|
|
|
|
static OSSL_FUNC_decoder_gettable_params_fn der2key_gettable_params;
|
|
|
|
static OSSL_FUNC_decoder_get_params_fn der2key_get_params;
|
|
|
|
static OSSL_FUNC_decoder_decode_fn der2key_decode;
|
|
|
|
static OSSL_FUNC_decoder_export_object_fn der2key_export_object;
|
2020-07-27 18:40:05 +02:00
|
|
|
|
|
|
|
typedef void *(extract_key_fn)(EVP_PKEY *);
|
|
|
|
typedef void (free_key_fn)(void *);
|
|
|
|
struct keytype_desc_st {
|
|
|
|
int type; /* EVP key type */
|
|
|
|
const char *name; /* Keytype */
|
|
|
|
const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* These must be the correct EVP_PKEY_get1_{TYPE}() and {TYPE}_free()
|
|
|
|
* function for the key.
|
|
|
|
*/
|
|
|
|
extract_key_fn *extract_key;
|
|
|
|
free_key_fn *free_key;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
2020-08-16 21:25:08 +02:00
|
|
|
* Context used for DER to key decoding.
|
2020-07-27 18:40:05 +02:00
|
|
|
*/
|
|
|
|
struct der2key_ctx_st {
|
|
|
|
PROV_CTX *provctx;
|
|
|
|
const struct keytype_desc_st *desc;
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct der2key_ctx_st *
|
|
|
|
der2key_newctx(void *provctx, const struct keytype_desc_st *desc)
|
|
|
|
{
|
|
|
|
struct der2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
|
|
|
|
|
|
|
|
if (ctx != NULL) {
|
|
|
|
ctx->provctx = provctx;
|
|
|
|
ctx->desc = desc;
|
|
|
|
}
|
|
|
|
return ctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void der2key_freectx(void *vctx)
|
|
|
|
{
|
|
|
|
struct der2key_ctx_st *ctx = vctx;
|
|
|
|
|
|
|
|
OPENSSL_free(ctx);
|
|
|
|
}
|
|
|
|
|
2020-08-05 13:23:32 +10:00
|
|
|
static const OSSL_PARAM *der2key_gettable_params(void *provctx)
|
2020-07-27 18:40:05 +02:00
|
|
|
{
|
|
|
|
static const OSSL_PARAM gettables[] = {
|
2020-08-16 21:25:08 +02:00
|
|
|
{ OSSL_DECODER_PARAM_INPUT_TYPE, OSSL_PARAM_UTF8_PTR, NULL, 0, 0 },
|
2020-07-27 18:40:05 +02:00
|
|
|
OSSL_PARAM_END,
|
|
|
|
};
|
|
|
|
|
|
|
|
return gettables;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int der2key_get_params(OSSL_PARAM params[])
|
|
|
|
{
|
|
|
|
OSSL_PARAM *p;
|
|
|
|
|
2020-08-16 21:25:08 +02:00
|
|
|
p = OSSL_PARAM_locate(params, OSSL_DECODER_PARAM_INPUT_TYPE);
|
2020-07-27 18:40:05 +02:00
|
|
|
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "DER"))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2020-08-16 21:25:08 +02:00
|
|
|
static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin,
|
|
|
|
OSSL_CALLBACK *data_cb, void *data_cbarg,
|
|
|
|
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
|
2020-07-27 18:40:05 +02:00
|
|
|
{
|
|
|
|
struct der2key_ctx_st *ctx = vctx;
|
2020-10-15 12:55:50 +03:00
|
|
|
void *libctx = PROV_LIBCTX_OF(ctx->provctx);
|
2020-07-27 18:40:05 +02:00
|
|
|
unsigned char *der = NULL;
|
|
|
|
const unsigned char *derp;
|
|
|
|
long der_len = 0;
|
|
|
|
unsigned char *new_der = NULL;
|
|
|
|
long new_der_len;
|
|
|
|
EVP_PKEY *pkey = NULL;
|
|
|
|
void *key = NULL;
|
2020-09-28 16:14:14 +02:00
|
|
|
int ok = 0;
|
2020-07-27 18:40:05 +02:00
|
|
|
|
2020-09-28 16:14:14 +02:00
|
|
|
SET_ERR_MARK();
|
2020-09-07 12:25:17 +02:00
|
|
|
if (!read_der(ctx->provctx, cin, &der, &der_len))
|
2020-09-16 12:52:09 +02:00
|
|
|
goto err;
|
2020-07-27 18:40:05 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Opportunistic attempt to decrypt. If it doesn't work, we try to
|
|
|
|
* decode our input unencrypted.
|
|
|
|
*/
|
2020-09-07 12:25:17 +02:00
|
|
|
if (der_from_p8(&new_der, &new_der_len, der, der_len, pw_cb, pw_cbarg)) {
|
2020-07-27 18:40:05 +02:00
|
|
|
OPENSSL_free(der);
|
|
|
|
der = new_der;
|
|
|
|
der_len = new_der_len;
|
|
|
|
}
|
2020-09-28 16:14:14 +02:00
|
|
|
RESET_ERR_MARK();
|
2020-07-27 18:40:05 +02:00
|
|
|
|
|
|
|
derp = der;
|
|
|
|
pkey = d2i_PrivateKey_ex(ctx->desc->type, NULL, &derp, der_len,
|
|
|
|
libctx, NULL);
|
|
|
|
if (pkey == NULL) {
|
2020-09-28 16:14:14 +02:00
|
|
|
RESET_ERR_MARK();
|
2020-07-27 18:40:05 +02:00
|
|
|
derp = der;
|
2020-08-18 20:39:45 +02:00
|
|
|
pkey = d2i_PUBKEY_ex(NULL, &derp, der_len, libctx, NULL);
|
2020-07-27 18:40:05 +02:00
|
|
|
}
|
|
|
|
|
2020-08-02 13:12:54 +02:00
|
|
|
if (pkey == NULL) {
|
2020-09-28 16:14:14 +02:00
|
|
|
RESET_ERR_MARK();
|
2020-08-02 13:12:54 +02:00
|
|
|
derp = der;
|
|
|
|
pkey = d2i_KeyParams(ctx->desc->type, NULL, &derp, der_len);
|
|
|
|
}
|
2020-09-16 12:52:09 +02:00
|
|
|
err:
|
|
|
|
/*
|
|
|
|
* Prune low-level ASN.1 parse errors from error queue, assuming that
|
|
|
|
* this is called by decoder_process() in a loop trying several formats.
|
|
|
|
*/
|
2020-09-28 16:14:14 +02:00
|
|
|
CLEAR_ERR_MARK();
|
2020-08-02 13:12:54 +02:00
|
|
|
|
2020-07-27 18:40:05 +02:00
|
|
|
if (pkey != NULL) {
|
|
|
|
/*
|
|
|
|
* Tear out the low-level key pointer from the pkey,
|
|
|
|
* but only if it matches the expected key type.
|
|
|
|
*
|
|
|
|
* TODO(3.0): The check should be done with EVP_PKEY_is_a(), but
|
|
|
|
* as long as we still have #legacy internal keys, it's safer to
|
2020-08-18 20:39:45 +02:00
|
|
|
* use the type numbers inside the provider.
|
2020-07-27 18:40:05 +02:00
|
|
|
*/
|
|
|
|
if (EVP_PKEY_id(pkey) == ctx->desc->type)
|
|
|
|
key = ctx->desc->extract_key(pkey);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ctx->desc->extract_key() is expected to have incremented |key|'s
|
|
|
|
* reference count, so it should be safe to free |pkey| now.
|
|
|
|
*/
|
|
|
|
EVP_PKEY_free(pkey);
|
|
|
|
}
|
|
|
|
|
|
|
|
OPENSSL_free(der);
|
|
|
|
|
|
|
|
if (key != NULL) {
|
CORE: Define provider-native abstract objects
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)
2020-07-22 15:34:25 +02:00
|
|
|
OSSL_PARAM params[4];
|
|
|
|
int object_type = OSSL_OBJECT_PKEY;
|
2020-07-27 18:40:05 +02:00
|
|
|
|
|
|
|
params[0] =
|
CORE: Define provider-native abstract objects
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)
2020-07-22 15:34:25 +02:00
|
|
|
OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
|
|
|
|
params[1] =
|
|
|
|
OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
|
2020-07-27 18:40:05 +02:00
|
|
|
(char *)ctx->desc->name, 0);
|
|
|
|
/* The address of the key becomes the octet string */
|
CORE: Define provider-native abstract objects
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)
2020-07-22 15:34:25 +02:00
|
|
|
params[2] =
|
|
|
|
OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
|
2020-07-27 18:40:05 +02:00
|
|
|
&key, sizeof(key));
|
CORE: Define provider-native abstract objects
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)
2020-07-22 15:34:25 +02:00
|
|
|
params[3] = OSSL_PARAM_construct_end();
|
2020-07-27 18:40:05 +02:00
|
|
|
|
|
|
|
ok = data_cb(params, data_cbarg);
|
|
|
|
}
|
|
|
|
ctx->desc->free_key(key);
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int der2key_export_object(void *vctx,
|
|
|
|
const void *reference, size_t reference_sz,
|
|
|
|
OSSL_CALLBACK *export_cb, void *export_cbarg)
|
|
|
|
{
|
|
|
|
struct der2key_ctx_st *ctx = vctx;
|
|
|
|
OSSL_FUNC_keymgmt_export_fn *export =
|
|
|
|
ossl_prov_get_keymgmt_export(ctx->desc->fns);
|
|
|
|
void *keydata;
|
|
|
|
|
|
|
|
if (reference_sz == sizeof(keydata) && export != NULL) {
|
|
|
|
/* The contents of the reference is the address to our object */
|
|
|
|
keydata = *(void **)reference;
|
|
|
|
|
|
|
|
return export(keydata, OSSL_KEYMGMT_SELECT_ALL,
|
|
|
|
export_cb, export_cbarg);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define IMPLEMENT_NEWCTX(KEYTYPEstr, KEYTYPE, keytype, extract, free) \
|
|
|
|
static const struct keytype_desc_st keytype##_desc = \
|
2020-09-28 12:28:29 +10:00
|
|
|
{ EVP_PKEY_##KEYTYPE, KEYTYPEstr, \
|
|
|
|
ossl_##keytype##_keymgmt_functions, \
|
2020-07-27 18:40:05 +02:00
|
|
|
(extract_key_fn *)extract, \
|
|
|
|
(free_key_fn *)free }; \
|
2020-09-07 12:25:17 +02:00
|
|
|
static OSSL_FUNC_decoder_newctx_fn der2##keytype##_newctx; \
|
2020-07-27 18:40:05 +02:00
|
|
|
static void *der2##keytype##_newctx(void *provctx) \
|
|
|
|
{ \
|
|
|
|
return der2key_newctx(provctx, &keytype##_desc); \
|
|
|
|
} \
|
2020-09-28 12:28:29 +10:00
|
|
|
const OSSL_DISPATCH ossl_der_to_##keytype##_decoder_functions[] = { \
|
2020-08-16 21:25:08 +02:00
|
|
|
{ OSSL_FUNC_DECODER_NEWCTX, \
|
2020-07-27 18:40:05 +02:00
|
|
|
(void (*)(void))der2##keytype##_newctx }, \
|
2020-08-16 21:25:08 +02:00
|
|
|
{ OSSL_FUNC_DECODER_FREECTX, \
|
2020-07-27 18:40:05 +02:00
|
|
|
(void (*)(void))der2key_freectx }, \
|
2020-08-16 21:25:08 +02:00
|
|
|
{ OSSL_FUNC_DECODER_GETTABLE_PARAMS, \
|
2020-07-27 18:40:05 +02:00
|
|
|
(void (*)(void))der2key_gettable_params }, \
|
2020-08-16 21:25:08 +02:00
|
|
|
{ OSSL_FUNC_DECODER_GET_PARAMS, \
|
2020-07-27 18:40:05 +02:00
|
|
|
(void (*)(void))der2key_get_params }, \
|
2020-08-16 21:25:08 +02:00
|
|
|
{ OSSL_FUNC_DECODER_DECODE, \
|
|
|
|
(void (*)(void))der2key_decode }, \
|
|
|
|
{ OSSL_FUNC_DECODER_EXPORT_OBJECT, \
|
2020-07-27 18:40:05 +02:00
|
|
|
(void (*)(void))der2key_export_object }, \
|
|
|
|
{ 0, NULL } \
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef OPENSSL_NO_DH
|
|
|
|
IMPLEMENT_NEWCTX("DH", DH, dh, EVP_PKEY_get1_DH, DH_free);
|
2020-08-04 11:39:49 +10:00
|
|
|
IMPLEMENT_NEWCTX("DHX", DHX, dhx, EVP_PKEY_get1_DH, DH_free);
|
2020-07-27 18:40:05 +02:00
|
|
|
#endif
|
|
|
|
#ifndef OPENSSL_NO_DSA
|
|
|
|
IMPLEMENT_NEWCTX("DSA", DSA, dsa, EVP_PKEY_get1_DSA, DSA_free);
|
|
|
|
#endif
|
|
|
|
#ifndef OPENSSL_NO_EC
|
|
|
|
IMPLEMENT_NEWCTX("EC", EC, ec, EVP_PKEY_get1_EC_KEY, EC_KEY_free);
|
|
|
|
IMPLEMENT_NEWCTX("X25519", X25519, x25519,
|
2020-09-25 12:12:22 +10:00
|
|
|
evp_pkey_get1_X25519, ecx_key_free);
|
2020-07-27 18:40:05 +02:00
|
|
|
IMPLEMENT_NEWCTX("X448", X448, x448,
|
2020-09-25 12:12:22 +10:00
|
|
|
evp_pkey_get1_X448, ecx_key_free);
|
2020-07-27 18:40:05 +02:00
|
|
|
IMPLEMENT_NEWCTX("ED25519", ED25519, ed25519,
|
2020-09-25 12:12:22 +10:00
|
|
|
evp_pkey_get1_ED25519, ecx_key_free);
|
|
|
|
IMPLEMENT_NEWCTX("ED448", ED448, ed448, evp_pkey_get1_ED448, ecx_key_free);
|
2020-07-27 18:40:05 +02:00
|
|
|
#endif
|
|
|
|
IMPLEMENT_NEWCTX("RSA", RSA, rsa, EVP_PKEY_get1_RSA, RSA_free);
|
|
|
|
IMPLEMENT_NEWCTX("RSA-PSS", RSA_PSS, rsapss, EVP_PKEY_get1_RSA, RSA_free);
|