Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions SymCryptProvider/src/keymgmt/p_scossl_rsa_keymgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,69 @@ static BOOL p_scossl_rsa_keymgmt_has(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, int s
return ret;
}

static SCOSSL_STATUS p_scossl_rsa_keymgmt_validate(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx, int selection)
{
SCOSSL_STATUS success = SCOSSL_SUCCESS;
UINT64 pubExp = 0;
PBYTE pbModulus = NULL;
PBYTE pbPrivateExponent = NULL;
SYMCRYPT_ERROR scError;

UINT32 cbModulus = SymCryptRsakeySizeofModulus(keyCtx->key);
printf("\n Megan is here #####################");
if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY)
{
pbModulus = OPENSSL_malloc(cbModulus);
if (pbModulus == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return SCOSSL_FAILURE;
}

scError = SymCryptRsakeyGetValue(
keyCtx->key,
pbModulus, cbModulus,
&pubExp, 1,
NULL, NULL, 0,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0);
OPENSSL_free(pbModulus);

if (scError != SYMCRYPT_NO_ERROR)
{
SCOSSL_PROV_LOG_SYMCRYPT_ERROR("SymCryptRsakeyGetValue failed", scError);
return SCOSSL_FAILURE;
}
}

if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY)
{
pbPrivateExponent = OPENSSL_secure_malloc(cbModulus);
if (pbPrivateExponent == NULL)
{
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return SCOSSL_FAILURE;
}

scError = SymCryptRsakeyGetCrtValue(
keyCtx->key,
NULL, NULL, 0,
NULL, 0,
pbPrivateExponent, cbModulus,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0);
OPENSSL_secure_clear_free(pbPrivateExponent, cbModulus);

if (scError != SYMCRYPT_NO_ERROR)
{
SCOSSL_PROV_LOG_SYMCRYPT_ERROR("SymCryptRsakeyGetCrtValue failed", scError);
return SCOSSL_FAILURE;
}
}

return success;
}

static BOOL p_scossl_rsa_keymgmt_match(_In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx1, _In_ SCOSSL_PROV_RSA_KEY_CTX *keyCtx2,
int selection)
{
Expand Down Expand Up @@ -1364,6 +1427,7 @@ const OSSL_DISPATCH p_scossl_rsa_keymgmt_functions[] = {
{OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))p_scossl_rsa_keymgmt_get_params},
{OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))p_scossl_rsa_keymgmt_gettable_params},
{OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))p_scossl_rsa_keymgmt_has},
{OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))p_scossl_rsa_keymgmt_validate},
{OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))p_scossl_rsa_keymgmt_match},
{OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))p_scossl_rsa_keymgmt_impexp_types},
{OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))p_scossl_rsa_keymgmt_impexp_types},
Expand All @@ -1383,6 +1447,7 @@ const OSSL_DISPATCH p_scossl_rsapss_keymgmt_functions[] = {
{OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))p_scossl_rsa_keymgmt_get_params},
{OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))p_scossl_rsa_keymgmt_gettable_params},
{OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))p_scossl_rsa_keymgmt_has},
{OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))p_scossl_rsa_keymgmt_validate},
{OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))p_scossl_rsa_keymgmt_match},
{OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))p_scossl_rsa_keymgmt_impexp_types},
{OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))p_scossl_rsa_keymgmt_impexp_types},
Expand Down
59 changes: 58 additions & 1 deletion test/SslPlay/SslPlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,63 @@ void TestRsaEncryptDecrypt(
return;
}

#include <openssl/param_build.h>

void TestRsaPrivateCheckWithIncompleteKey()
{
printf("\nTesting EVP_PKEY_private_check with incomplete RSA key\n");

BIGNUM *n = NULL, *e = NULL;
RSA *rsa = NULL;
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *check_ctx = NULL;
int ret = 0;

// Construct public key parts
BN_hex2bn(&n, "C34F"); // Small modulus (for testing only)
e = BN_new();
BN_set_word(e, RSA_F4); // Common exponent = 65537

// Create RSA object and assign only n and e
rsa = RSA_new();
if (!RSA_set0_key(rsa, n, e, NULL)) {
handleOpenSSLError("RSA_set0_key failed");
goto end;
}
// Ownership of n and e transferred to RSA, do not free manually

// Wrap RSA into EVP_PKEY
pkey = EVP_PKEY_new();
if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
handleOpenSSLError("EVP_PKEY_assign_RSA failed");
goto end;
}
// Ownership of rsa transferred to pkey, do not free rsa manually

// Create a context to check private key validity
check_ctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!check_ctx) {
handleOpenSSLError("EVP_PKEY_CTX_new failed");
goto end;
}

// Perform the private check (should fail due to missing private parts)
ret = EVP_PKEY_private_check(check_ctx);
if (ret == 1) {
printf("❌ Unexpected success: EVP_PKEY_private_check returned 1\n");
} else {
printf("✅ Expected failure: EVP_PKEY_private_check returned error\n");
handleOpenSSLError("EVP_PKEY_private_check failed");
}

end:
EVP_PKEY_free(pkey);
EVP_PKEY_CTX_free(check_ctx);
// Don't free rsa, n, or e here — they're owned by EVP_PKEY now
}



void TestRsaSignVerify(
EVP_PKEY *signingKey,
EVP_PKEY *verificationKey,
Expand Down Expand Up @@ -2610,7 +2667,7 @@ int main(int argc, char** argv)
TestEcc();
TestDh();
TestHMAC();

TestRsaPrivateCheckWithIncompleteKey();
#ifdef SCOSSL_SSHKDF
TestSshKdf();
#endif
Expand Down