Support public key and param check in EVP interface

EVP_PKEY_public_check() and EVP_PKEY_param_check()

Doc and test cases are added

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4647)
This commit is contained in:
Paul Yang 2017-11-01 00:45:24 +08:00 committed by Richard Levitte
parent 5d99881e6a
commit b000470873
27 changed files with 510 additions and 33 deletions

View file

@ -18,7 +18,7 @@ typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_INFORM, OPT_OUTFORM, OPT_PASSIN, OPT_PASSOUT, OPT_ENGINE,
OPT_IN, OPT_OUT, OPT_PUBIN, OPT_PUBOUT, OPT_TEXT_PUB,
OPT_TEXT, OPT_NOOUT, OPT_MD, OPT_TRADITIONAL, OPT_CHECK
OPT_TEXT, OPT_NOOUT, OPT_MD, OPT_TRADITIONAL, OPT_CHECK, OPT_PUB_CHECK
} OPTION_CHOICE;
const OPTIONS pkey_options[] = {
@ -42,6 +42,7 @@ const OPTIONS pkey_options[] = {
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
{"check", OPT_CHECK, '-', "Check key consistency"},
{"pubcheck", OPT_PUB_CHECK, '-', "Check public key consistency"},
{NULL}
};
@ -56,7 +57,7 @@ int pkey_main(int argc, char **argv)
OPTION_CHOICE o;
int informat = FORMAT_PEM, outformat = FORMAT_PEM;
int pubin = 0, pubout = 0, pubtext = 0, text = 0, noout = 0, ret = 1;
int private = 0, traditional = 0, check = 0;
int private = 0, traditional = 0, check = 0, pub_check = 0;
prog = opt_init(argc, argv, pkey_options);
while ((o = opt_next()) != OPT_EOF) {
@ -114,6 +115,9 @@ int pkey_main(int argc, char **argv)
case OPT_CHECK:
check = 1;
break;
case OPT_PUB_CHECK:
pub_check = 1;
break;
case OPT_MD:
if (!opt_cipher(opt_unknown(), &cipher))
goto opthelp;
@ -143,7 +147,7 @@ int pkey_main(int argc, char **argv)
if (pkey == NULL)
goto end;
if (check) {
if (check || pub_check) {
int r;
EVP_PKEY_CTX *ctx;
@ -153,7 +157,10 @@ int pkey_main(int argc, char **argv)
goto end;
}
r = EVP_PKEY_check(ctx);
if (check)
r = EVP_PKEY_check(ctx);
else
r = EVP_PKEY_public_check(ctx);
if (r == 1) {
BIO_printf(out, "Key is valid\n");

View file

@ -16,7 +16,8 @@
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT, OPT_ENGINE
OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT,
OPT_ENGINE, OPT_CHECK
} OPTION_CHOICE;
const OPTIONS pkeyparam_options[] = {
@ -28,6 +29,7 @@ const OPTIONS pkeyparam_options[] = {
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
{"check", OPT_CHECK, '-', "Check key param consistency"},
{NULL}
};
@ -36,7 +38,7 @@ int pkeyparam_main(int argc, char **argv)
ENGINE *e = NULL;
BIO *in = NULL, *out = NULL;
EVP_PKEY *pkey = NULL;
int text = 0, noout = 0, ret = 1;
int text = 0, noout = 0, ret = 1, check = 0;
OPTION_CHOICE o;
char *infile = NULL, *outfile = NULL, *prog;
@ -67,6 +69,9 @@ int pkeyparam_main(int argc, char **argv)
case OPT_NOOUT:
noout = 1;
break;
case OPT_CHECK:
check = 1;
break;
}
}
argc = opt_num_rest();
@ -86,6 +91,38 @@ int pkeyparam_main(int argc, char **argv)
goto end;
}
if (check) {
int r;
EVP_PKEY_CTX *ctx;
ctx = EVP_PKEY_CTX_new(pkey, e);
if (ctx == NULL) {
ERR_print_errors(bio_err);
goto end;
}
r = EVP_PKEY_param_check(ctx);
if (r == 1) {
BIO_printf(out, "Parameters are valid\n");
} else {
/*
* Note: at least for RSA keys if this function returns
* -1, there will be no error reasons.
*/
unsigned long err;
BIO_printf(out, "Parameters are invalid\n");
while ((err = ERR_peek_error()) != 0) {
BIO_printf(out, "Detailed error: %s\n",
ERR_reason_error_string(err));
ERR_get_error(); /* remove err from error stack */
}
}
EVP_PKEY_CTX_free(ctx);
}
if (!noout)
PEM_write_bio_Parameters(out, pkey);

View file

@ -382,3 +382,15 @@ void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth,
{
ameth->pkey_check = pkey_check;
}
void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_pub_check) (const EVP_PKEY *pk))
{
ameth->pkey_public_check = pkey_pub_check;
}
void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_param_check) (const EVP_PKEY *pk))
{
ameth->pkey_param_check = pkey_param_check;
}

View file

@ -509,6 +509,25 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
}
static int dh_pkey_public_check(const EVP_PKEY *pkey)
{
DH *dh = pkey->pkey.dh;
if (dh->pub_key == NULL) {
DHerr(DH_F_DH_PKEY_PUBLIC_CHECK, DH_R_MISSING_PUBKEY);
return 0;
}
return DH_check_pub_key_ex(dh, dh->pub_key);
}
static int dh_pkey_param_check(const EVP_PKEY *pkey)
{
DH *dh = pkey->pkey.dh;
return DH_check_ex(dh);
}
const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
EVP_PKEY_DH,
EVP_PKEY_DH,
@ -539,7 +558,13 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
0,
int_dh_free,
0
0,
0, 0, 0, 0, 0,
0,
dh_pkey_public_check,
dh_pkey_param_check
};
const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
@ -572,7 +597,13 @@ const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
0,
int_dh_free,
dh_pkey_ctrl
dh_pkey_ctrl,
0, 0, 0, 0, 0,
0,
dh_pkey_public_check,
dh_pkey_param_check
};
#ifndef OPENSSL_NO_CMS

View file

@ -18,6 +18,19 @@
* p is odd
* 1 < g < p - 1
*/
int DH_check_params_ex(const DH *dh)
{
int errflags = 0;
(void)DH_check_params(dh, &errflags);
if ((errflags & DH_CHECK_P_NOT_PRIME) != 0)
DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_CHECK_P_NOT_PRIME);
if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0)
DHerr(DH_F_DH_CHECK_PARAMS_EX, DH_R_NOT_SUITABLE_GENERATOR);
return errflags == 0;
}
int DH_check_params(const DH *dh, int *ret)
{
@ -61,6 +74,29 @@ int DH_check_params(const DH *dh, int *ret)
* for 5, p mod 10 == 3 or 7
* should hold.
*/
int DH_check_ex(const DH *dh)
{
int errflags = 0;
(void)DH_check(dh, &errflags);
if ((errflags & DH_NOT_SUITABLE_GENERATOR) != 0)
DHerr(DH_F_DH_CHECK_EX, DH_R_NOT_SUITABLE_GENERATOR);
if ((errflags & DH_CHECK_Q_NOT_PRIME) != 0)
DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_Q_NOT_PRIME);
if ((errflags & DH_CHECK_INVALID_Q_VALUE) != 0)
DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_INVALID_Q_VALUE);
if ((errflags & DH_CHECK_INVALID_J_VALUE) != 0)
DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_INVALID_J_VALUE);
if ((errflags & DH_UNABLE_TO_CHECK_GENERATOR) != 0)
DHerr(DH_F_DH_CHECK_EX, DH_R_UNABLE_TO_CHECK_GENERATOR);
if ((errflags & DH_CHECK_P_NOT_PRIME) != 0)
DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_PRIME);
if ((errflags & DH_CHECK_P_NOT_SAFE_PRIME) != 0)
DHerr(DH_F_DH_CHECK_EX, DH_R_CHECK_P_NOT_SAFE_PRIME);
return errflags == 0;
}
int DH_check(const DH *dh, int *ret)
{
@ -142,6 +178,22 @@ int DH_check(const DH *dh, int *ret)
return ok;
}
int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key)
{
int errflags = 0;
(void)DH_check(dh, &errflags);
if ((errflags & DH_CHECK_PUBKEY_TOO_SMALL) != 0)
DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_SMALL);
if ((errflags & DH_CHECK_PUBKEY_TOO_LARGE) != 0)
DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_TOO_LARGE);
if ((errflags & DH_CHECK_PUBKEY_INVALID) != 0)
DHerr(DH_F_DH_CHECK_PUB_KEY_EX, DH_R_CHECK_PUBKEY_INVALID);
return errflags == 0;
}
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
{
int ok = 0;

View file

@ -18,6 +18,9 @@ static const ERR_STRING_DATA DH_str_functs[] = {
{ERR_PACK(ERR_LIB_DH, DH_F_DHPARAMS_PRINT_FP, 0), "DHparams_print_fp"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_BUILTIN_GENPARAMS, 0),
"dh_builtin_genparams"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_EX, 0), "DH_check_ex"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PARAMS_EX, 0), "DH_check_params_ex"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CHECK_PUB_KEY_EX, 0), "DH_check_pub_key_ex"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_DECRYPT, 0), "dh_cms_decrypt"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_PEERKEY, 0), "dh_cms_set_peerkey"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_CMS_SET_SHARED_INFO, 0),
@ -28,6 +31,8 @@ static const ERR_STRING_DATA DH_str_functs[] = {
{ERR_PACK(ERR_LIB_DH, DH_F_DH_NEW_BY_NID, 0), "DH_new_by_nid"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_NEW_METHOD, 0), "DH_new_method"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_PARAM_DECODE, 0), "dh_param_decode"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_PKEY_PUBLIC_CHECK, 0),
"dh_pkey_public_check"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_PRIV_DECODE, 0), "dh_priv_decode"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_PRIV_ENCODE, 0), "dh_priv_encode"},
{ERR_PACK(ERR_LIB_DH, DH_F_DH_PUB_DECODE, 0), "dh_pub_decode"},
@ -44,6 +49,20 @@ static const ERR_STRING_DATA DH_str_reasons[] = {
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "bad generator"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_DECODE_ERROR), "bn decode error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_ERROR), "bn error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_INVALID_J_VALUE),
"check invalid j value"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_INVALID_Q_VALUE),
"check invalid q value"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_PUBKEY_INVALID),
"check pubkey invalid"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_PUBKEY_TOO_LARGE),
"check pubkey too large"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_PUBKEY_TOO_SMALL),
"check pubkey too small"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_P_NOT_PRIME), "check p not prime"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_P_NOT_SAFE_PRIME),
"check p not safe prime"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_Q_NOT_PRIME), "check q not prime"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_DECODE_ERROR), "decode error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PARAMETER_NAME),
"invalid parameter name"},
@ -52,13 +71,18 @@ static const ERR_STRING_DATA DH_str_reasons[] = {
{ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PUBKEY), "invalid public key"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR),
"not suitable generator"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PRIVATE_VALUE), "no private value"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR),
"parameter encoding error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"},
{ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR),
"unable to check generator"},
{0, NULL}
};

View file

@ -533,6 +533,35 @@ static int ec_pkey_check(const EVP_PKEY *pkey)
return EC_KEY_check_key(eckey);
}
static int ec_pkey_public_check(const EVP_PKEY *pkey)
{
EC_KEY *eckey = pkey->pkey.ec;
/*
* Note: it unnecessary to check eckey->pub_key here since
* it will be checked in EC_KEY_check_key(). In fact, the
* EC_KEY_check_key() mainly checks the public key, and checks
* the private key optionally (only if there is one). So if
* someone passes a whole EC key (public + private), this
* will also work...
*/
return EC_KEY_check_key(eckey);
}
static int ec_pkey_param_check(const EVP_PKEY *pkey)
{
EC_KEY *eckey = pkey->pkey.ec;
/* stay consistent to what EVP_PKEY_check demands */
if (eckey->group == NULL) {
ECerr(EC_F_EC_PKEY_PARAM_CHECK, EC_R_MISSING_PARAMETERS);
return 0;
}
return EC_GROUP_check(eckey->group, NULL);
}
const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
EVP_PKEY_EC,
EVP_PKEY_EC,
@ -568,7 +597,9 @@ const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = {
0, 0, 0,
ec_pkey_check
ec_pkey_check,
ec_pkey_public_check,
ec_pkey_param_check
};
int EC_KEY_print(BIO *bp, const EC_KEY *x, int off)

View file

@ -182,6 +182,7 @@ static const ERR_STRING_DATA EC_str_functs[] = {
{ERR_PACK(ERR_LIB_EC, EC_F_EC_KEY_SIMPLE_PRIV2OCT, 0),
"ec_key_simple_priv2oct"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_CHECK, 0), "ec_pkey_check"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_PKEY_PARAM_CHECK, 0), "ec_pkey_param_check"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINTS_MAKE_AFFINE, 0),
"EC_POINTs_make_affine"},
{ERR_PACK(ERR_LIB_EC, EC_F_EC_POINT_ADD, 0), "EC_POINT_add"},

View file

@ -351,6 +351,9 @@ CT_F_SCT_SET_VERSION:104:SCT_set_version
DH_F_COMPUTE_KEY:102:compute_key
DH_F_DHPARAMS_PRINT_FP:101:DHparams_print_fp
DH_F_DH_BUILTIN_GENPARAMS:106:dh_builtin_genparams
DH_F_DH_CHECK_EX:121:DH_check_ex
DH_F_DH_CHECK_PARAMS_EX:122:DH_check_params_ex
DH_F_DH_CHECK_PUB_KEY_EX:123:DH_check_pub_key_ex
DH_F_DH_CMS_DECRYPT:114:dh_cms_decrypt
DH_F_DH_CMS_SET_PEERKEY:115:dh_cms_set_peerkey
DH_F_DH_CMS_SET_SHARED_INFO:116:dh_cms_set_shared_info
@ -360,6 +363,7 @@ DH_F_DH_METH_SET1_NAME:119:DH_meth_set1_name
DH_F_DH_NEW_BY_NID:104:DH_new_by_nid
DH_F_DH_NEW_METHOD:105:DH_new_method
DH_F_DH_PARAM_DECODE:107:dh_param_decode
DH_F_DH_PKEY_PUBLIC_CHECK:124:dh_pkey_public_check
DH_F_DH_PRIV_DECODE:110:dh_priv_decode
DH_F_DH_PRIV_ENCODE:111:dh_priv_encode
DH_F_DH_PUB_DECODE:108:dh_pub_decode
@ -542,6 +546,7 @@ EC_F_EC_KEY_SIMPLE_CHECK_KEY:258:ec_key_simple_check_key
EC_F_EC_KEY_SIMPLE_OCT2PRIV:259:ec_key_simple_oct2priv
EC_F_EC_KEY_SIMPLE_PRIV2OCT:260:ec_key_simple_priv2oct
EC_F_EC_PKEY_CHECK:273:ec_pkey_check
EC_F_EC_PKEY_PARAM_CHECK:274:ec_pkey_param_check
EC_F_EC_POINTS_MAKE_AFFINE:136:EC_POINTs_make_affine
EC_F_EC_POINT_ADD:112:EC_POINT_add
EC_F_EC_POINT_CMP:113:EC_POINT_cmp
@ -692,6 +697,8 @@ EVP_F_EVP_PKEY_KEYGEN_INIT:147:EVP_PKEY_keygen_init
EVP_F_EVP_PKEY_NEW:106:EVP_PKEY_new
EVP_F_EVP_PKEY_PARAMGEN:148:EVP_PKEY_paramgen
EVP_F_EVP_PKEY_PARAMGEN_INIT:149:EVP_PKEY_paramgen_init
EVP_F_EVP_PKEY_PARAM_CHECK:189:EVP_PKEY_param_check
EVP_F_EVP_PKEY_PUBLIC_CHECK:190:EVP_PKEY_public_check
EVP_F_EVP_PKEY_SET1_ENGINE:187:EVP_PKEY_set1_engine
EVP_F_EVP_PKEY_SIGN:140:EVP_PKEY_sign
EVP_F_EVP_PKEY_SIGN_INIT:141:EVP_PKEY_sign_init
@ -1794,18 +1801,29 @@ CT_R_UNSUPPORTED_VERSION:103:unsupported version
DH_R_BAD_GENERATOR:101:bad generator
DH_R_BN_DECODE_ERROR:109:bn decode error
DH_R_BN_ERROR:106:bn error
DH_R_CHECK_INVALID_J_VALUE:115:check invalid j value
DH_R_CHECK_INVALID_Q_VALUE:116:check invalid q value
DH_R_CHECK_PUBKEY_INVALID:122:check pubkey invalid
DH_R_CHECK_PUBKEY_TOO_LARGE:123:check pubkey too large
DH_R_CHECK_PUBKEY_TOO_SMALL:124:check pubkey too small
DH_R_CHECK_P_NOT_PRIME:117:check p not prime
DH_R_CHECK_P_NOT_SAFE_PRIME:118:check p not safe prime
DH_R_CHECK_Q_NOT_PRIME:119:check q not prime
DH_R_DECODE_ERROR:104:decode error
DH_R_INVALID_PARAMETER_NAME:110:invalid parameter name
DH_R_INVALID_PARAMETER_NID:114:invalid parameter nid
DH_R_INVALID_PUBKEY:102:invalid public key
DH_R_KDF_PARAMETER_ERROR:112:kdf parameter error
DH_R_KEYS_NOT_SET:108:keys not set
DH_R_MISSING_PUBKEY:125:missing pubkey
DH_R_MODULUS_TOO_LARGE:103:modulus too large
DH_R_NOT_SUITABLE_GENERATOR:120:not suitable generator
DH_R_NO_PARAMETERS_SET:107:no parameters set
DH_R_NO_PRIVATE_VALUE:100:no private value
DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error
DH_R_PEER_KEY_ERROR:111:peer key error
DH_R_SHARED_INFO_ERROR:113:shared info error
DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator
DSA_R_BAD_Q_VALUE:102:bad q value
DSA_R_BN_DECODE_ERROR:108:bn decode error
DSA_R_BN_ERROR:109:bn error

View file

@ -96,6 +96,10 @@ static const ERR_STRING_DATA EVP_str_functs[] = {
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN, 0), "EVP_PKEY_paramgen"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAMGEN_INIT, 0),
"EVP_PKEY_paramgen_init"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PARAM_CHECK, 0),
"EVP_PKEY_param_check"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_PUBLIC_CHECK, 0),
"EVP_PKEY_public_check"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SET1_ENGINE, 0),
"EVP_PKEY_set1_engine"},
{ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_PKEY_SIGN, 0), "EVP_PKEY_sign"},

View file

@ -191,3 +191,49 @@ int EVP_PKEY_check(EVP_PKEY_CTX *ctx)
return pkey->ameth->pkey_check(pkey);
}
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx)
{
EVP_PKEY *pkey = ctx->pkey;
if (pkey == NULL) {
EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK, EVP_R_NO_KEY_SET);
return 0;
}
/* call customized public key check function first */
if (ctx->pmeth->public_check != NULL)
return ctx->pmeth->public_check(pkey);
/* use default public key check function in ameth */
if (pkey->ameth == NULL || pkey->ameth->pkey_public_check == NULL) {
EVPerr(EVP_F_EVP_PKEY_PUBLIC_CHECK,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
return pkey->ameth->pkey_public_check(pkey);
}
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx)
{
EVP_PKEY *pkey = ctx->pkey;
if (pkey == NULL) {
EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK, EVP_R_NO_KEY_SET);
return 0;
}
/* call customized param check function first */
if (ctx->pmeth->param_check != NULL)
return ctx->pmeth->param_check(pkey);
/* use default param check function in ameth */
if (pkey->ameth == NULL || pkey->ameth->pkey_param_check == NULL) {
EVPerr(EVP_F_EVP_PKEY_PARAM_CHECK,
EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return -2;
}
return pkey->ameth->pkey_param_check(pkey);
}

View file

@ -630,6 +630,18 @@ void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
pmeth->check = check;
}
void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey))
{
pmeth->public_check = check;
}
void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey))
{
pmeth->param_check = check;
}
void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth,
int (**pinit) (EVP_PKEY_CTX *ctx))
{
@ -803,3 +815,17 @@ void EVP_PKEY_meth_get_check(EVP_PKEY_METHOD *pmeth,
if (*pcheck)
*pcheck = pmeth->check;
}
void EVP_PKEY_meth_get_public_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey))
{
if (*pcheck)
*pcheck = pmeth->public_check;
}
void EVP_PKEY_meth_get_param_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey))
{
if (*pcheck)
*pcheck = pmeth->param_check;
}

View file

@ -56,6 +56,8 @@ struct evp_pkey_asn1_method_st {
const ASN1_STRING *sig);
/* Check */
int (*pkey_check) (const EVP_PKEY *pk);
int (*pkey_public_check) (const EVP_PKEY *pk);
int (*pkey_param_check) (const EVP_PKEY *pk);
} /* EVP_PKEY_ASN1_METHOD */ ;
DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)

View file

@ -76,6 +76,8 @@ struct evp_pkey_method_st {
size_t siglen, const unsigned char *tbs,
size_t tbslen);
int (*check) (EVP_PKEY *pkey);
int (*public_check) (EVP_PKEY *pkey);
int (*param_check) (EVP_PKEY *pkey);
} /* EVP_PKEY_METHOD */ ;
DEFINE_STACK_OF_CONST(EVP_PKEY_METHOD)

View file

@ -24,6 +24,7 @@ B<openssl> B<pkey>
[B<-pubout>]
[B<-engine id>]
[B<-check>]
[B<-pubcheck>]
=head1 DESCRIPTION
@ -117,6 +118,11 @@ for all available algorithms.
This option checks the consistency of a key pair for both public and private
components.
=item B<-pubcheck>
This option checks the correctness of either a public key or the public component
of a key pair.
=back
=head1 EXAMPLES

View file

@ -14,6 +14,7 @@ B<openssl> B<pkeyparam>
[B<-text>]
[B<-noout>]
[B<-engine id>]
[B<-check>]
=head1 DESCRIPTION
@ -53,6 +54,10 @@ to attempt to obtain a functional reference to the specified engine,
thus initialising it if needed. The engine will then be set as the default
for all available algorithms.
=item B<-check>
This option checks the correctness of parameters.
=back
=head1 EXAMPLE

View file

@ -3,7 +3,9 @@
=head1 NAME
DH_generate_parameters_ex, DH_generate_parameters,
DH_check, DH_check_params - generate and check Diffie-Hellman
DH_check, DH_check_params,
DH_check_ex, DH_check_params_ex, DH_check_pub_key_ex
- generate and check Diffie-Hellman
parameters
=head1 SYNOPSIS
@ -15,6 +17,10 @@ parameters
int DH_check(DH *dh, int *codes);
int DH_check_params(DH *dh, int *codes);
int DH_check_ex(const DH *dh);
int DH_check_params_ex(const DH *dh);
int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key);
Deprecated:
#if OPENSSL_API_COMPAT < 0x00908000L
@ -105,6 +111,11 @@ The parameter B<j> is invalid.
=back
DH_check_ex(), DH_check_params() and DH_check_pub_key_ex() are similiar with
DH_check() and DH_check_params() respectively, but the error reasons are set
to the OpenSSL error handling framework instead of returning by the function
parameters.
=head1 RETURN VALUES
DH_generate_parameters_ex(), DH_check() and DH_check_params() return 1
@ -113,6 +124,9 @@ if the check could be performed, 0 otherwise.
DH_generate_parameters() returns a pointer to the DH structure or NULL if
the parameter generation fails.
DH_check_ex(), DH_check_params() and DH_check_pub_key_ex() return 1 if the
check is successful, 0 for failed.
The error codes can be obtained by L<ERR_get_error(3)>.
=head1 SEE ALSO
@ -127,7 +141,7 @@ DH_generate_parameters_ex() instead.
=head1 COPYRIGHT
Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
Licensed under the OpenSSL license (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy

View file

@ -16,6 +16,8 @@ EVP_PKEY_asn1_set_ctrl,
EVP_PKEY_asn1_set_item,
EVP_PKEY_asn1_set_siginf,
EVP_PKEY_asn1_set_check,
EVP_PKEY_asn1_set_public_check,
EVP_PKEY_asn1_set_param_check,
EVP_PKEY_asn1_set_security_bits,
EVP_PKEY_get0_asn1
- manipulating and registering EVP_PKEY_ASN1_METHOD structure
@ -100,6 +102,12 @@ EVP_PKEY_get0_asn1
void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_check) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_pub_check) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_param_check) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_security_bits) (const EVP_PKEY
*pk));
@ -309,10 +317,15 @@ It's called as part of L<X509_check_purpose(3)>, L<X509_check_ca(3)>
and L<X509_check_issued(3)>.
int (*pkey_check) (const EVP_PKEY *pk);
int (*pkey_public_check) (const EVP_PKEY *pk);
int (*pkey_param_check) (const EVP_PKEY *pk);
The pkey_check() method is used to check the validity of B<pk>.
It MUST return 0 for an invalid key, or 1 for a valid key.
It's called by L<EVP_PKEY_check(3)>.
The pkey_check(), pkey_public_check() and pkey_param_check() methods are used
to check the validity of B<pk> for key-pair, public component and parameters,
respectively.
They MUST return 0 for an invalid key, or 1 for a valid key.
They are called by L<EVP_PKEY_check(3)>, L<EVP_PKEY_public_check(3)> and
L<EVP_PKEY_param_check(3)> respectively.
=head2 Functions
@ -354,7 +367,8 @@ when initializing the application.
EVP_PKEY_asn1_set_public(), EVP_PKEY_asn1_set_private(),
EVP_PKEY_asn1_set_param(), EVP_PKEY_asn1_set_free(),
EVP_PKEY_asn1_set_ctrl(), EVP_PKEY_asn1_set_item(),
EVP_PKEY_asn1_set_siginf(), EVP_PKEY_asn1_set_check(), and
EVP_PKEY_asn1_set_siginf(), EVP_PKEY_asn1_set_check(),
EVP_PKEY_asn1_set_public_check(), EVP_PKEY_asn1_set_param_check() and
EVP_PKEY_asn1_set_security_bits() set the diverse methods of the given
B<EVP_PKEY_ASN1_METHOD> object.

View file

@ -6,7 +6,8 @@ EVP_PKEY_keygen_init, EVP_PKEY_keygen, EVP_PKEY_paramgen_init,
EVP_PKEY_paramgen, EVP_PKEY_CTX_set_cb, EVP_PKEY_CTX_get_cb,
EVP_PKEY_CTX_get_keygen_info, EVP_PKEY_CTX_set_app_data,
EVP_PKEY_CTX_get_app_data,
EVP_PKEY_gen_cb, EVP_PKEY_check
EVP_PKEY_gen_cb, EVP_PKEY_check, EVP_PKEY_public_check,
EVP_PKEY_param_check
- key and parameter generation and check functions
=head1 SYNOPSIS
@ -29,6 +30,8 @@ EVP_PKEY_gen_cb, EVP_PKEY_check
void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx);
int EVP_PKEY_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
=head1 DESCRIPTION
@ -64,6 +67,14 @@ EVP_PKEY_check() validates the key-pair given by B<ctx>. This function first tri
to use customized key check method in B<EVP_PKEY_METHOD> if it's present; otherwise
it calls a default one defined in B<EVP_PKEY_ASN1_METHOD>.
EVP_PKEY_public_check() validates the public component of the key-pair given by B<ctx>.
This function first tries to use customized key check method in B<EVP_PKEY_METHOD>
if it's present; otherwise it calls a default one defined in B<EVP_PKEY_ASN1_METHOD>.
EVP_PKEY_param_check() validates the algorithm parameters of the key-pair given by B<ctx>.
This function first tries to use customized key check method in B<EVP_PKEY_METHOD>
if it's present; otherwise it calls a default one defined in B<EVP_PKEY_ASN1_METHOD>.
=head1 NOTES
After the call to EVP_PKEY_keygen_init() or EVP_PKEY_paramgen_init() algorithm
@ -95,8 +106,9 @@ EVP_PKEY_paramgen() return 1 for success and 0 or a negative value for failure.
In particular a return value of -2 indicates the operation is not supported by
the public key algorithm.
EVP_PKEY_check() returns 1 for success or others for failure. It
returns -2 if the operation is not supported for the specific algorithm.
EVP_PKEY_check(), EVP_PKEY_public_check() and EVP_PKEY_param_check() return 1
for success or others for failure. They return -2 if the operation is not supported
for the specific algorithm.
=head1 EXAMPLES
@ -178,6 +190,9 @@ L<EVP_PKEY_derive(3)>
These functions were first added to OpenSSL 1.0.0.
EVP_PKEY_check(), EVP_PKEY_public_check() and EVP_PKEY_param_check() were added
in OpenSSL 1.1.1.
=head1 COPYRIGHT
Copyright 2006-2017 The OpenSSL Project Authors. All Rights Reserved.

View file

@ -9,11 +9,13 @@ EVP_PKEY_meth_set_paramgen, EVP_PKEY_meth_set_keygen, EVP_PKEY_meth_set_sign,
EVP_PKEY_meth_set_verify, EVP_PKEY_meth_set_verify_recover, EVP_PKEY_meth_set_signctx,
EVP_PKEY_meth_set_verifyctx, EVP_PKEY_meth_set_encrypt, EVP_PKEY_meth_set_decrypt,
EVP_PKEY_meth_set_derive, EVP_PKEY_meth_set_ctrl, EVP_PKEY_meth_set_check,
EVP_PKEY_meth_set_public_check, EVP_PKEY_meth_set_param_check,
EVP_PKEY_meth_get_init, EVP_PKEY_meth_get_copy, EVP_PKEY_meth_get_cleanup,
EVP_PKEY_meth_get_paramgen, EVP_PKEY_meth_get_keygen, EVP_PKEY_meth_get_sign,
EVP_PKEY_meth_get_verify, EVP_PKEY_meth_get_verify_recover, EVP_PKEY_meth_get_signctx,
EVP_PKEY_meth_get_verifyctx, EVP_PKEY_meth_get_encrypt, EVP_PKEY_meth_get_decrypt,
EVP_PKEY_meth_get_derive, EVP_PKEY_meth_get_ctrl, EVP_PKEY_meth_get_check,
EVP_PKEY_meth_get_public_check, EVP_PKEY_meth_get_param_check,
EVP_PKEY_meth_remove
- manipulating EVP_PKEY_METHOD structure
@ -110,6 +112,10 @@ EVP_PKEY_meth_remove
const char *value));
void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey));
void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey));
void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey));
void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth,
int (**pinit) (EVP_PKEY_CTX *ctx));
@ -191,6 +197,10 @@ EVP_PKEY_meth_remove
const char *value));
void EVP_PKEY_meth_get_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey));
void EVP_PKEY_meth_get_public_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey));
void EVP_PKEY_meth_get_param_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey));
=head1 DESCRIPTION
@ -316,9 +326,13 @@ a signature in a one-shot mode. They could be called by L<EVP_DigetSign(3)>
and L<EVP_DigestVerify(3)>.
int (*check) (EVP_PKEY *pkey);
int (*public_check) (EVP_PKEY *pkey);
int (*param_check) (EVP_PKEY *pkey);
The check() method is used to validate a key-pair for a given B<pkey>. It
could be called by L<EVP_PKEY_check(3)>.
The check(), public_check() and param_check() methods are used to validate a
key-pair, the public component and parameters respectively for a given B<pkey>.
They could be called by L<EVP_PKEY_check(3)>, L<EVP_PKEY_public_check(3)> and
L<EVP_PKEY_param_check(3)> respectively.
=head2 Functions

View file

@ -142,6 +142,9 @@ DEPRECATEDIN_0_9_8(DH *DH_generate_parameters(int prime_len, int generator,
int DH_generate_parameters_ex(DH *dh, int prime_len, int generator,
BN_GENCB *cb);
int DH_check_params_ex(const DH *dh);
int DH_check_ex(const DH *dh);
int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key);
int DH_check_params(const DH *dh, int *ret);
int DH_check(const DH *dh, int *codes);
int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);

View file

@ -25,6 +25,9 @@ int ERR_load_DH_strings(void);
# define DH_F_COMPUTE_KEY 102
# define DH_F_DHPARAMS_PRINT_FP 101
# define DH_F_DH_BUILTIN_GENPARAMS 106
# define DH_F_DH_CHECK_EX 121
# define DH_F_DH_CHECK_PARAMS_EX 122
# define DH_F_DH_CHECK_PUB_KEY_EX 123
# define DH_F_DH_CMS_DECRYPT 114
# define DH_F_DH_CMS_SET_PEERKEY 115
# define DH_F_DH_CMS_SET_SHARED_INFO 116
@ -34,6 +37,7 @@ int ERR_load_DH_strings(void);
# define DH_F_DH_NEW_BY_NID 104
# define DH_F_DH_NEW_METHOD 105
# define DH_F_DH_PARAM_DECODE 107
# define DH_F_DH_PKEY_PUBLIC_CHECK 124
# define DH_F_DH_PRIV_DECODE 110
# define DH_F_DH_PRIV_ENCODE 111
# define DH_F_DH_PUB_DECODE 108
@ -50,17 +54,28 @@ int ERR_load_DH_strings(void);
# define DH_R_BAD_GENERATOR 101
# define DH_R_BN_DECODE_ERROR 109
# define DH_R_BN_ERROR 106
# define DH_R_CHECK_INVALID_J_VALUE 115
# define DH_R_CHECK_INVALID_Q_VALUE 116
# define DH_R_CHECK_PUBKEY_INVALID 122
# define DH_R_CHECK_PUBKEY_TOO_LARGE 123
# define DH_R_CHECK_PUBKEY_TOO_SMALL 124
# define DH_R_CHECK_P_NOT_PRIME 117
# define DH_R_CHECK_P_NOT_SAFE_PRIME 118
# define DH_R_CHECK_Q_NOT_PRIME 119
# define DH_R_DECODE_ERROR 104
# define DH_R_INVALID_PARAMETER_NAME 110
# define DH_R_INVALID_PARAMETER_NID 114
# define DH_R_INVALID_PUBKEY 102
# define DH_R_KDF_PARAMETER_ERROR 112
# define DH_R_KEYS_NOT_SET 108
# define DH_R_MISSING_PUBKEY 125
# define DH_R_MODULUS_TOO_LARGE 103
# define DH_R_NOT_SUITABLE_GENERATOR 120
# define DH_R_NO_PARAMETERS_SET 107
# define DH_R_NO_PRIVATE_VALUE 100
# define DH_R_PARAMETER_ENCODING_ERROR 105
# define DH_R_PEER_KEY_ERROR 111
# define DH_R_SHARED_INFO_ERROR 113
# define DH_R_UNABLE_TO_CHECK_GENERATOR 121
#endif

View file

@ -126,6 +126,7 @@ int ERR_load_EC_strings(void);
# define EC_F_EC_KEY_SIMPLE_OCT2PRIV 259
# define EC_F_EC_KEY_SIMPLE_PRIV2OCT 260
# define EC_F_EC_PKEY_CHECK 273
# define EC_F_EC_PKEY_PARAM_CHECK 274
# define EC_F_EC_POINTS_MAKE_AFFINE 136
# define EC_F_EC_POINT_ADD 112
# define EC_F_EC_POINT_CMP 113

View file

@ -1218,6 +1218,12 @@ void EVP_PKEY_asn1_set_siginf(EVP_PKEY_ASN1_METHOD *ameth,
void EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_check) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_pub_check) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_param_check) (const EVP_PKEY *pk));
void EVP_PKEY_asn1_set_security_bits(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_security_bits) (const EVP_PKEY
*pk));
@ -1367,6 +1373,8 @@ int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_public_check(EVP_PKEY_CTX *ctx);
int EVP_PKEY_param_check(EVP_PKEY_CTX *ctx);
void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb);
EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx);
@ -1468,6 +1476,12 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey));
void EVP_PKEY_meth_set_public_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey));
void EVP_PKEY_meth_set_param_check(EVP_PKEY_METHOD *pmeth,
int (*check) (EVP_PKEY *pkey));
void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth,
int (**pinit) (EVP_PKEY_CTX *ctx));
@ -1563,6 +1577,12 @@ void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth,
void EVP_PKEY_meth_get_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey));
void EVP_PKEY_meth_get_public_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey));
void EVP_PKEY_meth_get_param_check(EVP_PKEY_METHOD *pmeth,
int (**pcheck) (EVP_PKEY *pkey));
void EVP_add_alg_module(void);
int ERR_load_EVP_strings(void);

View file

@ -83,6 +83,8 @@ int ERR_load_EVP_strings(void);
# define EVP_F_EVP_PKEY_NEW 106
# define EVP_F_EVP_PKEY_PARAMGEN 148
# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149
# define EVP_F_EVP_PKEY_PARAM_CHECK 189
# define EVP_F_EVP_PKEY_PUBLIC_CHECK 190
# define EVP_F_EVP_PKEY_SET1_ENGINE 187
# define EVP_F_EVP_PKEY_SIGN 140
# define EVP_F_EVP_PKEY_SIGN_INIT 141

View file

@ -283,6 +283,22 @@ static const unsigned char kExampleBadECKeyDER[] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
};
/* prime256v1 */
static const unsigned char kExampleECPubKeyDER[] = {
0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
0x42, 0x00, 0x04, 0xba, 0xeb, 0x83, 0xfb, 0x3b, 0xb2, 0xff, 0x30, 0x53,
0xdb, 0xce, 0x32, 0xf2, 0xac, 0xae, 0x44, 0x0d, 0x3d, 0x13, 0x53, 0xb8,
0xd1, 0x68, 0x55, 0xde, 0x44, 0x46, 0x05, 0xa6, 0xc9, 0xd2, 0x04, 0xb7,
0xe3, 0xa2, 0x96, 0xc8, 0xb2, 0x5e, 0x22, 0x03, 0xd7, 0x03, 0x7a, 0x8b,
0x13, 0x5c, 0x42, 0x49, 0xc2, 0xab, 0x86, 0xd6, 0xac, 0x6b, 0x93, 0x20,
0x56, 0x6a, 0xc6, 0xc8, 0xa5, 0x0b, 0xe5
};
static const unsigned char pExampleECParamDER[] = {
0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07
};
#endif
typedef struct APK_DATA_st {
@ -290,6 +306,9 @@ typedef struct APK_DATA_st {
size_t size;
int evptype;
int check;
int pub_check;
int param_check;
int type; /* 0 for private, 1 for public, 2 for params */
} APK_DATA;
static APK_DATA keydata[] = {
@ -301,10 +320,14 @@ static APK_DATA keydata[] = {
};
static APK_DATA keycheckdata[] = {
{kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), EVP_PKEY_RSA, 1},
{kExampleBadRSAKeyDER, sizeof(kExampleBadRSAKeyDER), EVP_PKEY_RSA, 0},
{kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), EVP_PKEY_RSA, 1, -2, -2, 0},
{kExampleBadRSAKeyDER, sizeof(kExampleBadRSAKeyDER), EVP_PKEY_RSA,
0, -2, -2, 0},
#ifndef OPENSSL_NO_EC
{kExampleECKeyDER, sizeof(kExampleECKeyDER), EVP_PKEY_EC, 1}
{kExampleECKeyDER, sizeof(kExampleECKeyDER), EVP_PKEY_EC, 1, 1, 1, 0},
/* group is also associated in our pub key */
{kExampleECPubKeyDER, sizeof(kExampleECPubKeyDER), EVP_PKEY_EC, 0, 1, 1, 1},
{pExampleECParamDER, sizeof(pExampleECParamDER), EVP_PKEY_EC, 0, 0, 1, 2}
#endif
};
@ -458,6 +481,16 @@ static int pkey_custom_check(EVP_PKEY *pkey)
return 0xbeef;
}
static int pkey_custom_pub_check(EVP_PKEY *pkey)
{
return 0xbeef;
}
static int pkey_custom_param_check(EVP_PKEY *pkey)
{
return 0xbeef;
}
static EVP_PKEY_METHOD *custom_pmeth;
static int test_EVP_PKEY_check(int i)
@ -465,6 +498,7 @@ static int test_EVP_PKEY_check(int i)
int ret = 0;
const unsigned char *p;
EVP_PKEY *pkey = NULL;
EC_KEY *eckey = NULL;
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY_CTX *ctx2 = NULL;
const APK_DATA *ak = &keycheckdata[i];
@ -472,23 +506,44 @@ static int test_EVP_PKEY_check(int i)
size_t input_len = ak->size;
int expected_id = ak->evptype;
int expected_check = ak->check;
int expected_pub_check = ak->pub_check;
int expected_param_check = ak->param_check;
int type = ak->type;
BIO *pubkey = NULL;
p = input;
if (!TEST_ptr(pkey = d2i_AutoPrivateKey(NULL, &p, input_len))
|| !TEST_ptr_eq(p, input + input_len)
|| !TEST_int_eq(EVP_PKEY_id(pkey), expected_id))
if (type == 0 &&
(!TEST_ptr(pkey = d2i_AutoPrivateKey(NULL, &p, input_len))
|| !TEST_ptr_eq(p, input + input_len)
|| !TEST_int_eq(EVP_PKEY_id(pkey), expected_id)))
goto done;
if (type == 1 &&
(!TEST_ptr(pubkey = BIO_new_mem_buf(input, input_len))
|| !TEST_ptr(eckey = d2i_EC_PUBKEY_bio(pubkey, NULL))
|| !TEST_ptr(pkey = EVP_PKEY_new())
|| !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))))
goto done;
if (type == 2 &&
(!TEST_ptr(eckey = d2i_ECParameters(NULL, &p, input_len))
|| !TEST_ptr_eq(p, input + input_len)
|| !TEST_ptr(pkey = EVP_PKEY_new())
|| !TEST_true(EVP_PKEY_assign_EC_KEY(pkey, eckey))))
goto done;
if (!TEST_ptr(ctx = EVP_PKEY_CTX_new(pkey, NULL)))
goto done;
if (expected_check == 1) {
if (!TEST_int_eq(EVP_PKEY_check(ctx), 1))
goto done;
} else {
if (!TEST_int_ne(EVP_PKEY_check(ctx), 1))
goto done;
}
if (!TEST_int_eq(EVP_PKEY_check(ctx), expected_check))
goto done;
if (!TEST_int_eq(EVP_PKEY_public_check(ctx), expected_pub_check))
goto done;
if (!TEST_int_eq(EVP_PKEY_param_check(ctx), expected_param_check))
goto done;
ctx2 = EVP_PKEY_CTX_new_id(0xdefaced, NULL);
/* assign the pkey directly, as an internal test */
@ -498,12 +553,19 @@ static int test_EVP_PKEY_check(int i)
if (!TEST_int_eq(EVP_PKEY_check(ctx2), 0xbeef))
goto done;
if (!TEST_int_eq(EVP_PKEY_public_check(ctx2), 0xbeef))
goto done;
if (!TEST_int_eq(EVP_PKEY_param_check(ctx2), 0xbeef))
goto done;
ret = 1;
done:
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_CTX_free(ctx2);
EVP_PKEY_free(pkey);
BIO_free(pubkey);
return ret;
}
@ -519,6 +581,8 @@ int setup_tests(void)
if (!TEST_ptr(custom_pmeth))
return 0;
EVP_PKEY_meth_set_check(custom_pmeth, pkey_custom_check);
EVP_PKEY_meth_set_public_check(custom_pmeth, pkey_custom_pub_check);
EVP_PKEY_meth_set_param_check(custom_pmeth, pkey_custom_param_check);
if (!TEST_int_eq(EVP_PKEY_meth_add0(custom_pmeth), 1))
return 0;
ADD_ALL_TESTS(test_EVP_PKEY_check, OSSL_NELEM(keycheckdata));

View file

@ -4427,3 +4427,14 @@ EVP_sm4_ecb 4371 1_1_1 EXIST::FUNCTION:SM4
EVP_sm4_cfb128 4372 1_1_1 EXIST::FUNCTION:SM4
EVP_sm3 4373 1_1_1 EXIST::FUNCTION:SM3
OCSP_resp_get0_signer 4374 1_1_0h EXIST::FUNCTION:OCSP
EVP_PKEY_public_check 4375 1_1_1 EXIST::FUNCTION:
EVP_PKEY_param_check 4376 1_1_1 EXIST::FUNCTION:
EVP_PKEY_meth_set_public_check 4377 1_1_1 EXIST::FUNCTION:
EVP_PKEY_meth_set_param_check 4378 1_1_1 EXIST::FUNCTION:
EVP_PKEY_meth_get_public_check 4379 1_1_1 EXIST::FUNCTION:
EVP_PKEY_meth_get_param_check 4380 1_1_1 EXIST::FUNCTION:
EVP_PKEY_asn1_set_public_check 4381 1_1_1 EXIST::FUNCTION:
EVP_PKEY_asn1_set_param_check 4382 1_1_1 EXIST::FUNCTION:
DH_check_ex 4383 1_1_1 EXIST::FUNCTION:DH
DH_check_pub_key_ex 4384 1_1_1 EXIST::FUNCTION:DH
DH_check_params_ex 4385 1_1_1 EXIST::FUNCTION:DH