added EVP_PKEY_param_check

This commit is contained in:
Hideki Miyazaki
2021-04-15 14:56:07 +09:00
parent 31bc2e4114
commit e063984d17
3 changed files with 186 additions and 12 deletions

View File

@ -55368,18 +55368,6 @@ int wolfSSL_CTX_get_security_level(const WOLFSSL_CTX* ctx)
#ifndef NO_WOLFSSL_STUB
/**
* validate the algorithm parameters of the key-pair
* @param ctx a pointer to WOLFSSL_EVP_PKEY_CTX structure
* @return WOLFSSL_FAILURE for now
*/
int wolfSSL_EVP_PKEY_param_check(WOLFSSL_EVP_PKEY_CTX* ctx)
{
WOLFSSL_STUB("wolfSSL_EVP_PKEY_param_check");
(void)ctx;
return WOLFSSL_FAILURE;
}
/**
* set call back function for psk session use
* @param ssl a pointer to WOLFSSL structure

View File

@ -36790,6 +36790,60 @@ static void test_wolfSSL_QT_EVP_PKEY_CTX_free(void)
printf(resultFmt, passed);
#endif
}
static void test_wolfSSL_EVP_PKEY_param_check(void)
{
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
#if !defined(NO_DH) && !defined(NO_FILESYSTEM)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) \
&& (HAVE_FIPS_VERSION>2))
DH *dh = NULL;
DH *setDh = NULL;
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX* ctx = NULL;
FILE* f = NULL;
unsigned char buf[4096];
const unsigned char* pt = buf;
const char* dh2048 = "./certs/dh2048.der";
long len = 0;
int code = -1;
printf(testingFmt, "test_wolfSSL_EVP_PKEY_param_check");
XMEMSET(buf, 0, sizeof(buf));
f = XFOPEN(dh2048, "rb");
AssertTrue(f != XBADFILE);
len = (long)XFREAD(buf, 1, sizeof(buf), f);
XFCLOSE(f);
/* Load dh2048.der into DH with internal format */
AssertNotNull(setDh = d2i_DHparams(NULL, &pt, len));
AssertIntEQ(DH_check(setDh, &code), WOLFSSL_SUCCESS);
AssertIntEQ(code, 0);
code = -1;
pkey = wolfSSL_EVP_PKEY_new();
/* Set DH into PKEY */
AssertIntEQ(EVP_PKEY_set1_DH(pkey, setDh), WOLFSSL_SUCCESS);
/* create ctx from pkey */
AssertNotNull(ctx = EVP_PKEY_CTX_new(pkey, NULL));
AssertIntEQ(EVP_PKEY_param_check(ctx), 1/* valid */);
/* */
/* TO DO invlaid case */
/* */
EVP_PKEY_CTX_free(ctx);
EVP_PKEY_free(pkey);
DH_free(setDh);
DH_free(dh);
printf(resultFmt, passed);
#endif
#endif
#endif
}
static void test_wolfSSL_EVP_BytesToKey(void)
{
#if defined(OPENSSL_ALL) && !defined(NO_DES3)

View File

@ -2113,6 +2113,138 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_cmp(const WOLFSSL_EVP_PKEY *a, const WOLFSSL_EV
return ret;
}
/**
* validate DH algorithm parameters
* @param dh_key a pointer to WOLFSSL_EVP_PKEY_CTX structure
* @return WOLFSSL_SUCCESS on success, otherwise failure
*/
static int DH_param_check(WOLFSSL_DH* dh_key)
{
int ret = WOLFSSL_SUCCESS;
WOLFSSL_BN_CTX* ctx = NULL;
WOLFSSL_BIGNUM *num1 = NULL;
WOLFSSL_BIGNUM *num2 = NULL;
WOLFSSL_ENTER("DH_param_check");
ctx = wolfSSL_BN_CTX_new();
if (ctx == NULL) {
WOLFSSL_MSG("failed to allocate memory");
return WOLFSSL_FAILURE;
}
num1 = wolfSSL_BN_new();
num2 = wolfSSL_BN_new();
if (num1 == NULL || num2 == NULL) {
WOLFSSL_MSG("failed to assign big number");
ret = WOLFSSL_FAILURE;
}
/* prime check */
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_BN_is_odd(dh_key->p) == 0){
WOLFSSL_MSG("dh_key->p is not prime");
ret = WOLFSSL_FAILURE;
} /* TO DO safe prime check. need BN_rshift1 */
/* generator check */
if (ret == WOLFSSL_SUCCESS &&
(wolfSSL_BN_is_one(dh_key->g) ||
wolfSSL_BN_is_negative(dh_key->g) ||
wolfSSL_BN_is_zero(dh_key->g))) {
WOLFSSL_MSG("dh_key->g is not suitable generator");
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_BN_cmp(dh_key->p, dh_key->g) <= 0) {
WOLFSSL_MSG("dh_key->g is not suitable generator");
ret = WOLFSSL_FAILURE;
}
if (ret == WOLFSSL_SUCCESS &&
dh_key->q != NULL)
{
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_BN_mod_exp(num1, dh_key->g, dh_key->q, dh_key->p, ctx) ==
WOLFSSL_FAILURE) {
WOLFSSL_MSG("BN_mod_exp failed");
ret = WOLFSSL_FAILURE;
}
else
if (ret == WOLFSSL_SUCCESS &&
wolfSSL_BN_is_one(num1) == WOLFSSL_FAILURE) {
WOLFSSL_MSG("dh_key->g is not suitable generator");
ret = WOLFSSL_FAILURE;
}
/* test if the number q is prime. */
if (ret == WOLFSSL_SUCCESS &&
(wolfSSL_BN_is_prime_ex(dh_key->q, 64, ctx, NULL) <= 0)) {
WOLFSSL_MSG("dh_key->q is not prime or error during check.");
ret = WOLFSSL_FAILURE;
} /* else TO DO check q div q - 1. need BN_div */
}
/* clean up */
wolfSSL_BN_CTX_free(ctx);
wolfSSL_BN_free(num1);
wolfSSL_BN_free(num2);
WOLFSSL_LEAVE("DH_param_check", WOLFSSL_SUCCESS);
return ret;
}
/**
* validate the algorithm parameters
* @param ctx a pointer to WOLFSSL_EVP_PKEY_CTX structure
* @return WOLFSSL_SUCCESS on success, otherwise failure
*/
int wolfSSL_EVP_PKEY_param_check(WOLFSSL_EVP_PKEY_CTX* ctx)
{
int type;
int ret;
/* sanity check */
if (ctx == NULL) {
return WOLFSSL_FAILURE;
}
type = wolfSSL_EVP_PKEY_type(wolfSSL_EVP_PKEY_base_id(ctx->pkey));
switch(type) {
#if !defined(NO_RSA)
case EVP_PKEY_RSA:
WOLFSSL_MSG("not yet implemented");
return WOLFSSL_FAILURE;
#endif
#if defined(HAVE_ECC)
case EVP_PKEY_EC:
WOLFSSL_MSG("not yet implemented");
return WOLFSSL_FAILURE;
#endif
#if !defined(NO_DSA)
case EVP_PKEY_DSA:
WOLFSSL_MSG("not yet implemented");
return WOLFSSL_FAILURE;
#endif
#if defined(OPENSSL_ALL) || defined(WOLFSSL_QT)
#if !defined(NO_DH) && !defined(NO_FILESYSTEM)
#if !defined(HAVE_FIPS) || (defined(HAVE_FIPS_VERSION) \
&& (HAVE_FIPS_VERSION>2))
case EVP_PKEY_DH:
ret = DH_param_check(wolfSSL_EVP_PKEY_get1_DH(ctx->pkey));
return ret;
#endif
#endif
#endif
default:
WOLFSSL_MSG("Unknown PEKY type");
return WOLFSSL_FAILURE;
}
(void)ret;
(void)DH_param_check;
}
/* Initialize structure for signing
*
* ctx WOLFSSL_EVP_MD_CTX structure to initialize