mirror of https://github.com/openssl/openssl.git
Fix EVP_PKEY_new_mac_key()
EVP_PKEY_new_mac_key() was failing if the specified MAC was not available in the default provider - even though that MAC is never actually needed to successfully complete the function. The resulting EVP_PKEY can then be used in some non-default libctx which *does* have the MAC loaded. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/11360)
This commit is contained in:
parent
5f1adadce1
commit
129c22840e
|
@ -53,19 +53,25 @@ static int pkey_mac_init(EVP_PKEY_CTX *ctx)
|
||||||
int nid = ctx->pmeth->pkey_id;
|
int nid = ctx->pmeth->pkey_id;
|
||||||
EVP_MAC *mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
|
EVP_MAC *mac = EVP_MAC_fetch(ctx->libctx, OBJ_nid2sn(nid), ctx->propquery);
|
||||||
|
|
||||||
if (mac == NULL) {
|
/*
|
||||||
EVPerr(EVP_F_PKEY_MAC_INIT, EVP_R_FETCH_FAILED);
|
* mac == NULL may actually be ok in some situations. In an
|
||||||
return 0;
|
* EVP_PKEY_new_mac_key() call a temporary EVP_PKEY_CTX is created with
|
||||||
}
|
* default libctx. We don't actually need the underlying MAC to be present
|
||||||
|
* to successfully set the key in that case. The resulting EVP_PKEY could
|
||||||
|
* then be used in some other libctx where the MAC *is* present
|
||||||
|
*/
|
||||||
|
|
||||||
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
|
if ((hctx = OPENSSL_zalloc(sizeof(*hctx))) == NULL) {
|
||||||
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
|
EVPerr(EVP_F_PKEY_MAC_INIT, ERR_R_MALLOC_FAILURE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hctx->ctx = EVP_MAC_CTX_new(mac);
|
if (mac != NULL) {
|
||||||
if (hctx->ctx == NULL) {
|
hctx->ctx = EVP_MAC_CTX_new(mac);
|
||||||
OPENSSL_free(hctx);
|
if (hctx->ctx == NULL) {
|
||||||
return 0;
|
OPENSSL_free(hctx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nid == EVP_PKEY_CMAC) {
|
if (nid == EVP_PKEY_CMAC) {
|
||||||
|
@ -87,6 +93,13 @@ static int pkey_mac_copy(EVP_PKEY_CTX *dst, const EVP_PKEY_CTX *src)
|
||||||
MAC_PKEY_CTX *sctx, *dctx;
|
MAC_PKEY_CTX *sctx, *dctx;
|
||||||
|
|
||||||
sctx = EVP_PKEY_CTX_get_data(src);
|
sctx = EVP_PKEY_CTX_get_data(src);
|
||||||
|
|
||||||
|
if (sctx->ctx == NULL) {
|
||||||
|
/* This actually means the fetch failed during the init call */
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (sctx->ctx->data == NULL)
|
if (sctx->ctx->data == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -146,7 +159,7 @@ static void pkey_mac_cleanup(EVP_PKEY_CTX *ctx)
|
||||||
MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
|
MAC_PKEY_CTX *hctx = ctx == NULL ? NULL : EVP_PKEY_CTX_get_data(ctx);
|
||||||
|
|
||||||
if (hctx != NULL) {
|
if (hctx != NULL) {
|
||||||
EVP_MAC *mac = EVP_MAC_CTX_mac(hctx->ctx);
|
EVP_MAC *mac = hctx->ctx != NULL ? EVP_MAC_CTX_mac(hctx->ctx) : NULL;
|
||||||
|
|
||||||
switch (hctx->type) {
|
switch (hctx->type) {
|
||||||
case MAC_TYPE_RAW:
|
case MAC_TYPE_RAW:
|
||||||
|
@ -181,8 +194,15 @@ static int pkey_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
||||||
break;
|
break;
|
||||||
case MAC_TYPE_MAC:
|
case MAC_TYPE_MAC:
|
||||||
{
|
{
|
||||||
EVP_MAC_CTX *cmkey = EVP_MAC_CTX_dup(hctx->ctx);
|
EVP_MAC_CTX *cmkey;
|
||||||
|
|
||||||
|
if (hctx->ctx == NULL) {
|
||||||
|
/* This actually means the fetch failed during the init call */
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmkey = EVP_MAC_CTX_dup(hctx->ctx);
|
||||||
if (cmkey == NULL)
|
if (cmkey == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
|
if (!EVP_MAC_up_ref(EVP_MAC_CTX_mac(hctx->ctx)))
|
||||||
|
@ -224,6 +244,12 @@ static int pkey_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx)
|
||||||
hctx->type == MAC_TYPE_RAW
|
hctx->type == MAC_TYPE_RAW
|
||||||
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
|
&& (ctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) != 0;
|
||||||
|
|
||||||
|
if (hctx->ctx == NULL) {
|
||||||
|
/* This actually means the fetch failed during the init call */
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (set_key) {
|
if (set_key) {
|
||||||
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
|
if (!EVP_MAC_is_a(EVP_MAC_CTX_mac(hctx->ctx),
|
||||||
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
|
OBJ_nid2sn(EVP_PKEY_id(EVP_PKEY_CTX_get0_pkey(ctx)))))
|
||||||
|
@ -289,6 +315,14 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||||
ciphname, 0);
|
ciphname, 0);
|
||||||
params[params_n] = OSSL_PARAM_construct_end();
|
params[params_n] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
if (hctx->ctx == NULL) {
|
||||||
|
/*
|
||||||
|
* This actually means the fetch failed during the init call
|
||||||
|
*/
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|
if (!EVP_MAC_CTX_set_params(hctx->ctx, params)
|
||||||
|| !EVP_MAC_init(hctx->ctx))
|
|| !EVP_MAC_init(hctx->ctx))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -340,6 +374,14 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||||
params[0] =
|
params[0] =
|
||||||
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
|
OSSL_PARAM_construct_size_t(OSSL_MAC_PARAM_SIZE, &size);
|
||||||
|
|
||||||
|
if (hctx->ctx == NULL) {
|
||||||
|
/*
|
||||||
|
* This actually means the fetch failed during the init call
|
||||||
|
*/
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
|
if (!EVP_MAC_CTX_set_params(hctx->ctx, params))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -376,6 +418,14 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||||
p2, p1);
|
p2, p1);
|
||||||
params[params_n] = OSSL_PARAM_construct_end();
|
params[params_n] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
if (hctx->ctx == NULL) {
|
||||||
|
/*
|
||||||
|
* This actually means the fetch failed during the init call
|
||||||
|
*/
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
return EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -388,6 +438,12 @@ static int pkey_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
||||||
case EVP_PKEY_CTRL_DIGESTINIT:
|
case EVP_PKEY_CTRL_DIGESTINIT:
|
||||||
switch (hctx->type) {
|
switch (hctx->type) {
|
||||||
case MAC_TYPE_RAW:
|
case MAC_TYPE_RAW:
|
||||||
|
if (hctx->ctx == NULL) {
|
||||||
|
/* This actually means the fetch failed during the init call */
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Ensure that we have attached the implementation */
|
/* Ensure that we have attached the implementation */
|
||||||
if (!EVP_MAC_init(hctx->ctx))
|
if (!EVP_MAC_init(hctx->ctx))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -459,6 +515,13 @@ static int pkey_mac_ctrl_str(EVP_PKEY_CTX *ctx,
|
||||||
type, value, strlen(value) + 1, NULL))
|
type, value, strlen(value) + 1, NULL))
|
||||||
return 0;
|
return 0;
|
||||||
params[1] = OSSL_PARAM_construct_end();
|
params[1] = OSSL_PARAM_construct_end();
|
||||||
|
|
||||||
|
if (hctx->ctx == NULL) {
|
||||||
|
/* This actually means the fetch failed during the init call */
|
||||||
|
EVPerr(0, EVP_R_FETCH_FAILED);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
ok = EVP_MAC_CTX_set_params(hctx->ctx, params);
|
||||||
OPENSSL_free(params[0].data);
|
OPENSSL_free(params[0].data);
|
||||||
return ok;
|
return ok;
|
||||||
|
|
Loading…
Reference in New Issue