Latest update.

This commit is contained in:
2020-05-17 20:27:18 +09:00
parent ad9fce94c2
commit 3a6d64bb68
619 changed files with 13638 additions and 4698 deletions
+236 -79
View File
@@ -28,6 +28,7 @@
#include <openssl/cmac.h>
#include <openssl/engine.h>
#include <openssl/params.h>
#include <openssl/param_build.h>
#include <openssl/serializer.h>
#include <openssl/core_names.h>
@@ -36,6 +37,7 @@
#include "internal/evp.h"
#include "internal/provider.h"
#include "evp_local.h"
DEFINE_STACK_OF(X509_ATTRIBUTE)
#include "crypto/ec.h"
@@ -46,7 +48,7 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
int len, EVP_KEYMGMT *keymgmt);
static void evp_pkey_free_it(EVP_PKEY *key);
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
/* The type of parameters selected in key parameter functions */
# define SELECT_PARAMETERS OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
@@ -229,9 +231,11 @@ static int evp_pkey_cmp_any(const EVP_PKEY *a, const EVP_PKEY *b,
* us to compare types using legacy NIDs.
*/
if ((a->type != EVP_PKEY_NONE
&& !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type)))
&& (b->keymgmt == NULL
|| !EVP_KEYMGMT_is_a(b->keymgmt, OBJ_nid2sn(a->type))))
|| (b->type != EVP_PKEY_NONE
&& !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type))))
&& (a->keymgmt == NULL
|| !EVP_KEYMGMT_is_a(a->keymgmt, OBJ_nid2sn(b->type)))))
return -1; /* not the same key type */
/*
@@ -317,78 +321,213 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
return -2;
}
EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
const unsigned char *priv,
size_t len)
{
EVP_PKEY *ret = EVP_PKEY_new();
if (ret == NULL
|| !pkey_set_type(ret, e, type, NULL, -1, NULL)) {
static EVP_PKEY *new_raw_key_int(OPENSSL_CTX *libctx,
const char *strtype,
const char *propq,
int nidtype,
ENGINE *e,
const unsigned char *key,
size_t len,
int key_is_priv)
{
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
const EVP_PKEY_ASN1_METHOD *ameth = NULL;
int result = 0;
# ifndef OPENSSL_NO_ENGINE
/* Check if there is an Engine for this type */
if (e == NULL) {
ENGINE *tmpe = NULL;
if (strtype != NULL)
ameth = EVP_PKEY_asn1_find_str(&tmpe, strtype, -1);
else if (nidtype != EVP_PKEY_NONE)
ameth = EVP_PKEY_asn1_find(&tmpe, nidtype);
/* If tmpe is NULL then no engine is claiming to support this type */
if (tmpe == NULL)
ameth = NULL;
ENGINE_finish(tmpe);
}
# endif
if (e == NULL && ameth == NULL) {
/*
* No engine is claiming to support this type, so lets see if we have
* a provider.
*/
ctx = EVP_PKEY_CTX_new_from_name(libctx,
strtype != NULL ? strtype
: OBJ_nid2sn(nidtype),
propq);
if (ctx == NULL) {
EVPerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
/* May fail if no provider available */
ERR_set_mark();
if (EVP_PKEY_key_fromdata_init(ctx) == 1) {
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
ERR_clear_last_mark();
params[0] = OSSL_PARAM_construct_octet_string(
key_is_priv ? OSSL_PKEY_PARAM_PRIV_KEY
: OSSL_PKEY_PARAM_PUB_KEY,
(void *)key, len);
if (EVP_PKEY_fromdata(ctx, &pkey, params) != 1) {
EVPerr(0, EVP_R_KEY_SETUP_FAILED);
goto err;
}
EVP_PKEY_CTX_free(ctx);
return pkey;
}
ERR_pop_to_mark();
/* else not supported so fallback to legacy */
}
/* Legacy code path */
pkey = EVP_PKEY_new();
if (pkey == NULL) {
EVPerr(0, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!pkey_set_type(pkey, e, nidtype, strtype, -1, NULL)) {
/* EVPerr already called */
goto err;
}
if (ret->ameth->set_priv_key == NULL) {
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
if (!ossl_assert(pkey->ameth != NULL))
goto err;
if (key_is_priv) {
if (pkey->ameth->set_priv_key == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
goto err;
}
if (!pkey->ameth->set_priv_key(pkey, key, len)) {
EVPerr(0, EVP_R_KEY_SETUP_FAILED);
goto err;
}
} else {
if (pkey->ameth->set_pub_key == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
goto err;
}
if (!pkey->ameth->set_pub_key(pkey, key, len)) {
EVPerr(0, EVP_R_KEY_SETUP_FAILED);
goto err;
}
}
if (!ret->ameth->set_priv_key(ret, priv, len)) {
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PRIVATE_KEY, EVP_R_KEY_SETUP_FAILED);
goto err;
}
return ret;
result = 1;
err:
EVP_PKEY_free(ret);
return NULL;
if (!result) {
EVP_PKEY_free(pkey);
pkey = NULL;
}
EVP_PKEY_CTX_free(ctx);
return pkey;
}
EVP_PKEY *EVP_PKEY_new_raw_private_key_with_libctx(OPENSSL_CTX *libctx,
const char *keytype,
const char *propq,
const unsigned char *priv,
size_t len)
{
return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, priv,
len, 1);
}
EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *e,
const unsigned char *priv,
size_t len)
{
return new_raw_key_int(NULL, NULL, NULL, type, e, priv, len, 1);
}
EVP_PKEY *EVP_PKEY_new_raw_public_key_with_libctx(OPENSSL_CTX *libctx,
const char *keytype,
const char *propq,
const unsigned char *pub,
size_t len)
{
return new_raw_key_int(libctx, keytype, propq, EVP_PKEY_NONE, NULL, pub,
len, 0);
}
EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *e,
const unsigned char *pub,
size_t len)
{
EVP_PKEY *ret = EVP_PKEY_new();
return new_raw_key_int(NULL, NULL, NULL, type, e, pub, len, 0);
}
if (ret == NULL
|| !pkey_set_type(ret, e, type, NULL, -1, NULL)) {
/* EVPerr already called */
goto err;
struct raw_key_details_st
{
unsigned char **key;
size_t *len;
int selection;
};
static OSSL_CALLBACK get_raw_key_details;
static int get_raw_key_details(const OSSL_PARAM params[], void *arg)
{
const OSSL_PARAM *p = NULL;
struct raw_key_details_st *raw_key = arg;
if (raw_key->selection == OSSL_KEYMGMT_SELECT_PRIVATE_KEY) {
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY))
!= NULL)
return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
SIZE_MAX, raw_key->len);
} else if (raw_key->selection == OSSL_KEYMGMT_SELECT_PUBLIC_KEY) {
if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY))
!= NULL)
return OSSL_PARAM_get_octet_string(p, (void **)raw_key->key,
SIZE_MAX, raw_key->len);
}
if (ret->ameth->set_pub_key == NULL) {
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
goto err;
}
if (!ret->ameth->set_pub_key(ret, pub, len)) {
EVPerr(EVP_F_EVP_PKEY_NEW_RAW_PUBLIC_KEY, EVP_R_KEY_SETUP_FAILED);
goto err;
}
return ret;
err:
EVP_PKEY_free(ret);
return NULL;
return 0;
}
int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
size_t *len)
{
/* TODO(3.0) Do we need to do anything about provider side keys? */
if (pkey->ameth->get_priv_key == NULL) {
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
if (pkey->keymgmt != NULL) {
struct raw_key_details_st raw_key;
raw_key.key = priv == NULL ? NULL : &priv;
raw_key.len = len;
raw_key.selection = OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
return evp_keymgmt_export(pkey->keymgmt, pkey->keydata,
OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
get_raw_key_details, &raw_key);
}
if (pkey->ameth == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (pkey->ameth->get_priv_key == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (!pkey->ameth->get_priv_key(pkey, priv, len)) {
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PRIVATE_KEY, EVP_R_GET_RAW_KEY_FAILED);
EVPerr(0, EVP_R_GET_RAW_KEY_FAILED);
return 0;
}
@@ -398,7 +537,23 @@ int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, unsigned char *priv,
int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, unsigned char *pub,
size_t *len)
{
/* TODO(3.0) Do we need to do anything about provider side keys? */
if (pkey->keymgmt != NULL) {
struct raw_key_details_st raw_key;
raw_key.key = pub == NULL ? NULL : &pub;
raw_key.len = len;
raw_key.selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
return evp_keymgmt_export(pkey->keymgmt, pkey->keydata,
OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
get_raw_key_details, &raw_key);
}
if (pkey->ameth == NULL) {
EVPerr(0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (pkey->ameth->get_pub_key == NULL) {
EVPerr(EVP_F_EVP_PKEY_GET_RAW_PUBLIC_KEY,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
@@ -655,9 +810,9 @@ DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
return ret;
}
# endif /* OPENSSL_NO_DSA */
#endif /* FIPS_MODE */
#endif /* FIPS_MODULE */
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
# ifndef OPENSSL_NO_EC
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key)
{
@@ -751,7 +906,7 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey)
int EVP_PKEY_is_a(const EVP_PKEY *pkey, const char *name)
{
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
if (pkey->keymgmt == NULL) {
/*
* These hard coded cases are pure hackery to get around the fact
@@ -1063,9 +1218,9 @@ size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt)
return rv;
}
#endif /* FIPS_MODE */
#endif /* FIPS_MODULE */
/*- All methods below can also be used in FIPS_MODE */
/*- All methods below can also be used in FIPS_MODULE */
EVP_PKEY *EVP_PKEY_new(void)
{
@@ -1084,7 +1239,7 @@ EVP_PKEY *EVP_PKEY_new(void)
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
goto err;
}
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, ret, &ret->ex_data)) {
EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE);
goto err;
@@ -1114,7 +1269,7 @@ EVP_PKEY *EVP_PKEY_new(void)
static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
int len, EVP_KEYMGMT *keymgmt)
{
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
const EVP_PKEY_ASN1_METHOD *ameth = NULL;
ENGINE **eptr = (e == NULL) ? &e : NULL;
#endif
@@ -1132,13 +1287,13 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
if (pkey != NULL) {
int free_it = 0;
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
free_it = free_it || pkey->pkey.ptr != NULL;
#endif
free_it = free_it || pkey->keydata != NULL;
if (free_it)
evp_pkey_free_it(pkey);
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
/*
* If key type matches and a method exists then this lookup has
* succeeded once so just indicate success.
@@ -1156,7 +1311,7 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
# endif
#endif
}
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
if (str != NULL)
ameth = EVP_PKEY_asn1_find_str(eptr, str, len);
else if (type != EVP_PKEY_NONE)
@@ -1171,7 +1326,7 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
{
int check = 1;
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
check = check && ameth == NULL;
#endif
check = check && keymgmt == NULL;
@@ -1191,7 +1346,7 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
pkey->save_type = type;
pkey->type = type;
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
/*
* If the internal "origin" key is provider side, don't save |ameth|.
* The main reason is that |ameth| is one factor to detect that the
@@ -1209,16 +1364,18 @@ static int pkey_set_type(EVP_PKEY *pkey, ENGINE *e, int type, const char *str,
* to the |save_type| field, because |type| is supposed to be set
* to EVP_PKEY_NONE in that case.
*/
if (keymgmt != NULL)
pkey->save_type = ameth->pkey_id;
else if (pkey->ameth != NULL)
pkey->type = ameth->pkey_id;
if (ameth != NULL) {
if (keymgmt != NULL)
pkey->save_type = ameth->pkey_id;
else if (pkey->ameth != NULL)
pkey->type = ameth->pkey_id;
}
#endif
}
return 1;
}
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
static void find_ameth(const char *name, void *data)
{
const char **str = data;
@@ -1243,7 +1400,7 @@ static void find_ameth(const char *name, void *data)
int EVP_PKEY_set_type_by_keymgmt(EVP_PKEY *pkey, EVP_KEYMGMT *keymgmt)
{
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
# define EVP_PKEY_TYPE_STR str[0]
# define EVP_PKEY_TYPE_STRLEN (str[0] == NULL ? -1 : (int)strlen(str[0]))
/*
@@ -1282,7 +1439,7 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey)
return ((i > 1) ? 1 : 0);
}
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
void evp_pkey_free_legacy(EVP_PKEY *x)
{
if (x->ameth != NULL) {
@@ -1298,14 +1455,14 @@ void evp_pkey_free_legacy(EVP_PKEY *x)
# endif
x->type = EVP_PKEY_NONE;
}
#endif /* FIPS_MODE */
#endif /* FIPS_MODULE */
static void evp_pkey_free_it(EVP_PKEY *x)
{
/* internal function; x is never NULL */
evp_keymgmt_util_clear_operation_cache(x);
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
evp_pkey_free_legacy(x);
#endif
@@ -1330,11 +1487,11 @@ void EVP_PKEY_free(EVP_PKEY *x)
return;
REF_ASSERT_ISNT(i < 0);
evp_pkey_free_it(x);
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_EVP_PKEY, x, &x->ex_data);
#endif
CRYPTO_THREAD_lock_free(x->lock);
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free);
#endif
OPENSSL_free(x);
@@ -1346,7 +1503,7 @@ int EVP_PKEY_size(const EVP_PKEY *pkey)
if (pkey != NULL) {
size = pkey->cache.size;
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
if (pkey->ameth != NULL && pkey->ameth->pkey_size != NULL)
size = pkey->ameth->pkey_size(pkey);
#endif
@@ -1368,14 +1525,14 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
/* No key data => nothing to export */
check = 1;
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
check = check && pk->pkey.ptr == NULL;
#endif
check = check && pk->keydata == NULL;
if (check)
return NULL;
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
if (pk->pkey.ptr != NULL) {
/*
* If the legacy key doesn't have an dirty counter or export function,
@@ -1407,7 +1564,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
if (tmp_keymgmt == NULL)
goto end;
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
if (pk->pkey.ptr != NULL) {
size_t i = 0;
@@ -1479,7 +1636,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
pk->dirty_cnt_copy = pk->ameth->dirty_cnt(pk);
goto end;
}
#endif /* FIPS_MODE */
#endif /* FIPS_MODULE */
keydata = evp_keymgmt_util_export_to_provider(pk, tmp_keymgmt);
@@ -1499,7 +1656,7 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OPENSSL_CTX *libctx,
return keydata;
}
#ifndef FIPS_MODE
#ifndef FIPS_MODULE
int evp_pkey_downgrade(EVP_PKEY *pk)
{
EVP_KEYMGMT *keymgmt = pk->keymgmt;
@@ -1605,7 +1762,7 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
evp_keymgmt_util_cache_keyinfo(pk);
return 0; /* No downgrade, but at least the key is restored */
}
#endif /* FIPS_MODE */
#endif /* FIPS_MODULE */
const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey)
{