mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-05-11 00:49:41 +00:00
EVP: Add EVP_PKEY_get_default_digest_name() and use it
It is the provider version of EVP_PKEY_get_default_digest_nid(). We make sure to use it in the non-legacy section of do_sigver_init() (internal implementation for EVP_DigestSignInit() and EVP_DigestVerifyInit()) Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/10824)
This commit is contained in:
parent
c24937d5e7
commit
ead0d2347a
@ -33,6 +33,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
|||||||
EVP_SIGNATURE *signature = NULL;
|
EVP_SIGNATURE *signature = NULL;
|
||||||
EVP_KEYMGMT *tmp_keymgmt = NULL;
|
EVP_KEYMGMT *tmp_keymgmt = NULL;
|
||||||
const char *supported_sig = NULL;
|
const char *supported_sig = NULL;
|
||||||
|
char locmdname[80] = ""; /* 80 chars should be enough */
|
||||||
void *provkey = NULL;
|
void *provkey = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -63,22 +64,6 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
|||||||
if (locpctx->keytype == NULL)
|
if (locpctx->keytype == NULL)
|
||||||
goto legacy;
|
goto legacy;
|
||||||
|
|
||||||
if (mdname == NULL) {
|
|
||||||
if (type != NULL) {
|
|
||||||
mdname = EVP_MD_name(type);
|
|
||||||
} else if (pkey != NULL) {
|
|
||||||
/*
|
|
||||||
* TODO(v3.0) work out a better way for EVP_PKEYs with no legacy
|
|
||||||
* component.
|
|
||||||
*/
|
|
||||||
if (pkey->pkey.ptr != NULL) {
|
|
||||||
int def_nid;
|
|
||||||
if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
|
|
||||||
mdname = OBJ_nid2sn(def_nid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure that the key is provided. If not, go legacy */
|
/* Ensure that the key is provided. If not, go legacy */
|
||||||
tmp_keymgmt = locpctx->keymgmt;
|
tmp_keymgmt = locpctx->keymgmt;
|
||||||
provkey = evp_pkey_make_provided(locpctx->pkey, locpctx->libctx,
|
provkey = evp_pkey_make_provided(locpctx->pkey, locpctx->libctx,
|
||||||
@ -131,6 +116,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
|||||||
|
|
||||||
/* No more legacy from here down to legacy: */
|
/* No more legacy from here down to legacy: */
|
||||||
|
|
||||||
|
if (pctx != NULL)
|
||||||
|
*pctx = locpctx;
|
||||||
|
|
||||||
locpctx->op.sig.signature = signature;
|
locpctx->op.sig.signature = signature;
|
||||||
locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX
|
locpctx->operation = ver ? EVP_PKEY_OP_VERIFYCTX
|
||||||
: EVP_PKEY_OP_SIGNCTX;
|
: EVP_PKEY_OP_SIGNCTX;
|
||||||
@ -142,16 +130,26 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
|
|||||||
}
|
}
|
||||||
if (type != NULL) {
|
if (type != NULL) {
|
||||||
ctx->reqdigest = type;
|
ctx->reqdigest = type;
|
||||||
|
if (mdname == NULL)
|
||||||
|
mdname = EVP_MD_name(type);
|
||||||
} else {
|
} else {
|
||||||
|
if (mdname == NULL
|
||||||
|
&& EVP_PKEY_get_default_digest_name(locpctx->pkey, locmdname,
|
||||||
|
sizeof(locmdname)))
|
||||||
|
mdname = locmdname;
|
||||||
|
|
||||||
|
if (mdname != NULL) {
|
||||||
/*
|
/*
|
||||||
* This might be requested by a later call to EVP_MD_CTX_md(). In that
|
* This might be requested by a later call to EVP_MD_CTX_md().
|
||||||
* case the "explicit fetch" rules apply for that function (as per
|
* In that case the "explicit fetch" rules apply for that
|
||||||
* man pages), i.e. the ref count is not updated so the EVP_MD should
|
* function (as per man pages), i.e. the ref count is not updated
|
||||||
* not be used beyound the lifetime of the EVP_MD_CTX.
|
* so the EVP_MD should not be used beyound the lifetime of the
|
||||||
|
* EVP_MD_CTX.
|
||||||
*/
|
*/
|
||||||
ctx->reqdigest = ctx->fetched_digest =
|
ctx->reqdigest = ctx->fetched_digest =
|
||||||
EVP_MD_fetch(locpctx->libctx, mdname, props);
|
EVP_MD_fetch(locpctx->libctx, mdname, props);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ver) {
|
if (ver) {
|
||||||
if (signature->digest_verify_init == NULL) {
|
if (signature->digest_verify_init == NULL) {
|
||||||
|
@ -691,9 +691,39 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
|
|||||||
pctx);
|
pctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int legacy_asn1_ctrl_to_param(EVP_PKEY *pkey, int op,
|
||||||
|
int arg1, void *arg2)
|
||||||
|
{
|
||||||
|
if (pkey->pkeys[0].keymgmt == NULL)
|
||||||
|
return 0;
|
||||||
|
switch (op) {
|
||||||
|
case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
|
||||||
|
{
|
||||||
|
char mdname[80] = "";
|
||||||
|
int nid;
|
||||||
|
int rv = EVP_PKEY_get_default_digest_name(pkey, mdname,
|
||||||
|
sizeof(mdname));
|
||||||
|
|
||||||
|
if (rv <= 0)
|
||||||
|
return rv;
|
||||||
|
nid = OBJ_sn2nid(mdname);
|
||||||
|
if (nid == NID_undef)
|
||||||
|
nid = OBJ_ln2nid(mdname);
|
||||||
|
if (nid == NID_undef)
|
||||||
|
return 0;
|
||||||
|
*(int *)arg2 = nid;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
|
static int evp_pkey_asn1_ctrl(EVP_PKEY *pkey, int op, int arg1, void *arg2)
|
||||||
{
|
{
|
||||||
if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
|
if (pkey->ameth == NULL)
|
||||||
|
return legacy_asn1_ctrl_to_param(pkey, op, arg1, arg2);
|
||||||
|
if (pkey->ameth->pkey_ctrl == NULL)
|
||||||
return -2;
|
return -2;
|
||||||
return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
|
return pkey->ameth->pkey_ctrl(pkey, op, arg1, arg2);
|
||||||
}
|
}
|
||||||
@ -703,6 +733,45 @@ int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid)
|
|||||||
return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
|
return evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, 0, pnid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
|
||||||
|
char *mdname, size_t mdname_sz)
|
||||||
|
{
|
||||||
|
if (pkey->ameth == NULL) {
|
||||||
|
OSSL_PARAM params[3];
|
||||||
|
char mddefault[100] = "";
|
||||||
|
char mdmandatory[100] = "";
|
||||||
|
|
||||||
|
params[0] =
|
||||||
|
OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST,
|
||||||
|
mddefault, sizeof(mddefault));
|
||||||
|
params[1] =
|
||||||
|
OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MANDATORY_DIGEST,
|
||||||
|
mdmandatory,
|
||||||
|
sizeof(mdmandatory));
|
||||||
|
params[2] = OSSL_PARAM_construct_end();
|
||||||
|
if (!evp_keymgmt_get_key_params(pkey->pkeys[0].keymgmt,
|
||||||
|
pkey->pkeys[0].provdata,
|
||||||
|
params))
|
||||||
|
return 0;
|
||||||
|
if (mdmandatory[0] != '\0') {
|
||||||
|
OPENSSL_strlcpy(mdname, mdmandatory, mdname_sz);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
OPENSSL_strlcpy(mdname, mddefault, mdname_sz);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
int nid = NID_undef;
|
||||||
|
int rv = EVP_PKEY_get_default_digest_nid(pkey, &nid);
|
||||||
|
const char *name = rv > 0 ? OBJ_nid2sn(nid) : NULL;
|
||||||
|
|
||||||
|
if (rv > 0)
|
||||||
|
OPENSSL_strlcpy(mdname, name, mdname_sz);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
|
int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid)
|
||||||
{
|
{
|
||||||
int rv, default_nid;
|
int rv, default_nid;
|
||||||
|
@ -2,19 +2,32 @@
|
|||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
EVP_PKEY_get_default_digest_nid - get default signature digest
|
EVP_PKEY_get_default_digest_nid, EVP_PKEY_get_default_digest_name
|
||||||
|
- get default signature digest
|
||||||
|
|
||||||
=head1 SYNOPSIS
|
=head1 SYNOPSIS
|
||||||
|
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
|
|
||||||
|
int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
|
||||||
|
char *mdname, size_t mdname_sz)
|
||||||
int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
|
int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
The EVP_PKEY_get_default_digest_nid() function sets B<pnid> to the default
|
EVP_PKEY_get_default_digest_name() fills in the default message digest
|
||||||
message digest NID for the public key signature operations associated with key
|
name for the public key signature operations associated with key
|
||||||
B<pkey>. Note that some signature algorithms (i.e. Ed25519 and Ed448) do not use
|
I<pkey> into I<mdname>, up to at most I<mdname_sz> bytes including the
|
||||||
a digest during signing. In this case B<pnid> will be set to NID_undef.
|
ending NUL byte.
|
||||||
|
|
||||||
|
EVP_PKEY_get_default_digest_nid() sets I<pnid> to the default message
|
||||||
|
digest NID for the public key signature operations associated with key
|
||||||
|
I<pkey>. Note that some signature algorithms (i.e. Ed25519 and Ed448)
|
||||||
|
do not use a digest during signing. In this case I<pnid> will be set
|
||||||
|
to NID_undef. This function is only reliable for legacy keys, which
|
||||||
|
are keys with a B<EVP_PKEY_ASN1_METHOD>; these keys have typically
|
||||||
|
been loaded from engines, or created with L<EVP_PKEY_assign_RSA(3)> or
|
||||||
|
similar.
|
||||||
|
|
||||||
=head1 NOTES
|
=head1 NOTES
|
||||||
|
|
||||||
@ -22,11 +35,12 @@ For all current standard OpenSSL public key algorithms SHA256 is returned.
|
|||||||
|
|
||||||
=head1 RETURN VALUES
|
=head1 RETURN VALUES
|
||||||
|
|
||||||
The EVP_PKEY_get_default_digest_nid() function returns 1 if the message digest
|
EVP_PKEY_get_default_digest_name() and EVP_PKEY_get_default_digest_nid()
|
||||||
is advisory (that is other digests can be used) and 2 if it is mandatory (other
|
both return 1 if the message digest is advisory (that is other digests
|
||||||
digests can not be used). It returns 0 or a negative value for failure. In
|
can be used) and 2 if it is mandatory (other digests can not be used).
|
||||||
particular a return value of -2 indicates the operation is not supported by the
|
They return 0 or a negative value for failure. In particular a return
|
||||||
public key algorithm.
|
value of -2 indicates the operation is not supported by the public key
|
||||||
|
algorithm.
|
||||||
|
|
||||||
=head1 SEE ALSO
|
=head1 SEE ALSO
|
||||||
|
|
||||||
|
@ -158,6 +158,8 @@ extern "C" {
|
|||||||
#define OSSL_PKEY_PARAM_BITS "bits" /* integer */
|
#define OSSL_PKEY_PARAM_BITS "bits" /* integer */
|
||||||
#define OSSL_PKEY_PARAM_MAX_SIZE "max-size" /* integer */
|
#define OSSL_PKEY_PARAM_MAX_SIZE "max-size" /* integer */
|
||||||
#define OSSL_PKEY_PARAM_SECURITY_BITS "security-bits" /* integer */
|
#define OSSL_PKEY_PARAM_SECURITY_BITS "security-bits" /* integer */
|
||||||
|
#define OSSL_PKEY_PARAM_DEFAULT_DIGEST "default-digest" /* utf8 string */
|
||||||
|
#define OSSL_PKEY_PARAM_MANDATORY_DIGEST "mandatory-digest" /* utf8 string */
|
||||||
|
|
||||||
/* Diffie-Hellman/DSA Parameters */
|
/* Diffie-Hellman/DSA Parameters */
|
||||||
#define OSSL_PKEY_PARAM_FFC_P "p"
|
#define OSSL_PKEY_PARAM_FFC_P "p"
|
||||||
|
@ -1178,6 +1178,8 @@ int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
|
|||||||
int indent, ASN1_PCTX *pctx);
|
int indent, ASN1_PCTX *pctx);
|
||||||
|
|
||||||
int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
|
int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid);
|
||||||
|
int EVP_PKEY_get_default_digest_name(EVP_PKEY *pkey,
|
||||||
|
char *mdname, size_t mdname_sz);
|
||||||
int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid);
|
int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid);
|
||||||
|
|
||||||
int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
|
int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey,
|
||||||
|
@ -4912,3 +4912,4 @@ ASN1_UTCTIME_dup ? 3_0_0 EXIST::FUNCTION:
|
|||||||
ASN1_GENERALIZEDTIME_dup ? 3_0_0 EXIST::FUNCTION:
|
ASN1_GENERALIZEDTIME_dup ? 3_0_0 EXIST::FUNCTION:
|
||||||
RAND_priv_bytes_ex ? 3_0_0 EXIST::FUNCTION:
|
RAND_priv_bytes_ex ? 3_0_0 EXIST::FUNCTION:
|
||||||
RAND_bytes_ex ? 3_0_0 EXIST::FUNCTION:
|
RAND_bytes_ex ? 3_0_0 EXIST::FUNCTION:
|
||||||
|
EVP_PKEY_get_default_digest_name ? 3_0_0 EXIST::FUNCTION:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user