Refactor wc_CheckPrivateKey

- Change wc_CheckPrivateKey to wc_CheckPrivateKeyCert and wc_CheckPrivateKey
- wolfSSL_X509_check_private_key no longer needs to decode cert to check key
- Fix scope in api.c
This commit is contained in:
Juliusz Sosinowicz
2020-12-16 15:36:01 +01:00
parent dc266bc524
commit c03744db61
5 changed files with 67 additions and 64 deletions

View File

@ -7430,7 +7430,7 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
else
#endif
{
ret = wc_CheckPrivateKey(buff, size, der);
ret = wc_CheckPrivateKeyCert(buff, size, der);
if (ret == 1) {
ret = WOLFSSL_SUCCESS;
}
@ -8034,7 +8034,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl)
}
else
#endif
ret = wc_CheckPrivateKey(buff, size, &der);
ret = wc_CheckPrivateKeyCert(buff, size, &der);
FreeDecodedCert(&der);
return ret;
}
@ -19521,8 +19521,11 @@ static int wolfssl_conf_value_cmp(const WOLFSSL_CONF_VALUE *a,
}
}
/* Use MD5 for hashing as it is fast and should
* be good enough for database indexing */
/* Use MD5 for hashing as OpenSSL uses a hash algorithm that is
* "not as good as MD5, but still good" so using MD5 should
* be good enough for this application. The produced hashes don't
* need to line up between OpenSSL and wolfSSL. The hashes are for
* internal indexing only */
unsigned long wolfSSL_LH_strhash(const char *str)
{
unsigned long ret = 0;
@ -42617,11 +42620,6 @@ err:
int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key)
{
DecodedCert dc;
byte* der;
int derSz;
int ret;
WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
if (!x509 || !key) {
@ -42629,24 +42627,9 @@ err:
return WOLFSSL_FAILURE;
}
der = (byte*)wolfSSL_X509_get_der(x509, &derSz);
if (der == NULL) {
WOLFSSL_MSG("wolfSSL_X509_get_der error");
return WOLFSSL_FAILURE;
}
InitDecodedCert(&dc, der, derSz, x509->heap);
if (ParseCertRelative(&dc, CERT_TYPE, NO_VERIFY, NULL) != 0) {
FreeDecodedCert(&dc);
return WOLFSSL_FAILURE;
}
der = (byte*)key->pkey.ptr;
derSz = key->pkey_sz;
ret = wc_CheckPrivateKey(der, derSz, &dc);
FreeDecodedCert(&dc);
return ret == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
x509->pubKey.buffer, x509->pubKey.length,
x509->pubKeyOID) == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
}
/* wolfSSL uses negative values for error states. This function returns an

View File

@ -38249,8 +38249,8 @@ static void test_wolfSSL_d2i_X509_REQ(void)
AssertNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0));
AssertNotNull(at->value.asn1_string);
AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "2xIE+qqp/rhyTXP+");
#endif
AssertIntEQ(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), -1);
#endif
X509_free(req);
BIO_free(bio);
@ -38260,8 +38260,8 @@ static void test_wolfSSL_d2i_X509_REQ(void)
#ifdef OPENSSL_ALL
X509_ATTRIBUTE* attr;
ASN1_TYPE *at;
#endif
STACK_OF(X509_EXTENSION) *exts = NULL;
#endif
AssertNotNull(bio = BIO_new_file(csrExtFile, "rb"));
/* This CSR contains an Extension Request attribute so
* we test extension parsing in a CSR attribute here. */
@ -38277,10 +38277,10 @@ static void test_wolfSSL_d2i_X509_REQ(void)
*/
AssertIntEQ(X509_REQ_verify(req, pub_key), 1);
#ifdef OPENSSL_ALL
AssertNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(req));
AssertIntEQ(sk_X509_EXTENSION_num(exts), 2);
#ifdef OPENSSL_ALL
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
/*
* Obtain the challenge password from the CSR
*/
@ -38290,14 +38290,13 @@ static void test_wolfSSL_d2i_X509_REQ(void)
AssertNotNull(at = X509_ATTRIBUTE_get0_type(attr, 0));
AssertNotNull(at->value.asn1_string);
AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "IGCu/xNL4/0/wOgo");
#endif
AssertIntGE(X509_get_ext_by_NID(req, NID_key_usage, -1), 0);
AssertIntGE(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), 0);
#endif
X509_free(req);
BIO_free(bio);
EVP_PKEY_free(pub_key);
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
}
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST)
{

View File

@ -2904,25 +2904,29 @@ int wc_CreatePKCS8Key(byte* out, word32* outSz, byte* key, word32 keySz,
#endif /* HAVE_PKCS8 */
#if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY)
/* check that the private key is a pair for the public key in certificate
/* check that the private key is a pair for the public key
* return 1 (true) on match
* return 0 or negative value on failure/error
*
* key : buffer holding DER format key
* keySz : size of key buffer
* der : a initialized and parsed DecodedCert holding a certificate */
int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
* privKey : buffer holding DER format private key
* privKeySz : size of private key buffer
* pubKey : buffer holding DER format public key
* pubKeySz : size of public key buffer
* ks : type of key */
int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
const byte* pubKey, word32 pubKeySz, enum Key_Sum ks)
{
int ret;
(void)keySz;
(void)privKeySz;
(void)pubKeySz;
if (key == NULL || der == NULL) {
if (privKey == NULL || pubKey == NULL) {
return BAD_FUNC_ARG;
}
#if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
/* test if RSA key */
if (der->keyOID == RSAk) {
if (ks == RSAk) {
#ifdef WOLFSSL_SMALL_STACK
RsaKey* a;
RsaKey* b = NULL;
@ -2957,12 +2961,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif
return ret;
}
if ((ret = wc_RsaPrivateKeyDecode(key, &keyIdx, a, keySz)) == 0) {
if ((ret = wc_RsaPrivateKeyDecode(privKey, &keyIdx, a, privKeySz)) == 0) {
WOLFSSL_MSG("Checking RSA key pair");
keyIdx = 0; /* reset to 0 for parsing public key */
if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b,
der->pubKeySize)) == 0) {
if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
pubKeySz)) == 0) {
/* limit for user RSA crypto because of RsaKey
* dereference. */
#if defined(HAVE_USER_RSA)
@ -2991,7 +2995,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif /* !NO_RSA && !NO_ASN_CRYPT */
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT)
if (der->keyOID == ECDSAk) {
if (ks == ECDSAk) {
#ifdef WOLFSSL_SMALL_STACK
ecc_key* key_pair;
byte* privDer;
@ -3021,8 +3025,8 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
return ret;
}
if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair,
keySz)) == 0) {
if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
privKeySz)) == 0) {
WOLFSSL_MSG("Checking ECC key pair");
if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz))
@ -3030,9 +3034,9 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
wc_ecc_free(key_pair);
ret = wc_ecc_init(key_pair);
if (ret == 0) {
ret = wc_ecc_import_private_key((const byte*)privDer,
privSz, (const byte*)der->publicKey,
der->pubKeySize, key_pair);
ret = wc_ecc_import_private_key(privDer,
privSz, pubKey,
pubKeySz, key_pair);
}
/* public and private extracted successfully now check if is
@ -3056,7 +3060,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
#if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
if (der->keyOID == ED25519k) {
if (ks == ED25519k) {
#ifdef WOLFSSL_SMALL_STACK
ed25519_key* key_pair;
#else
@ -3077,12 +3081,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif
return ret;
}
if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair,
keySz)) == 0) {
if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
privKeySz)) == 0) {
WOLFSSL_MSG("Checking ED25519 key pair");
keyIdx = 0;
if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize,
key_pair)) == 0) {
if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
key_pair)) == 0) {
/* public and private extracted successfully no check if is
* a pair and also do sanity checks on key. wc_ecc_check_key
* checks that private * base generator equals pubkey */
@ -3099,7 +3103,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
#if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT)
if (der->keyOID == ED448k) {
if (ks == ED448k) {
#ifdef WOLFSSL_SMALL_STACK
ed448_key* key_pair = NULL;
#else
@ -3120,12 +3124,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif
return ret;
}
if ((ret = wc_Ed448PrivateKeyDecode(key, &keyIdx, key_pair,
keySz)) == 0) {
if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
privKeySz)) == 0) {
WOLFSSL_MSG("Checking ED448 key pair");
keyIdx = 0;
if ((ret = wc_ed448_import_public(der->publicKey, der->pubKeySize,
key_pair)) == 0) {
if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
key_pair)) == 0) {
/* public and private extracted successfully no check if is
* a pair and also do sanity checks on key. wc_ecc_check_key
* checks that private * base generator equals pubkey */
@ -3144,11 +3148,26 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
ret = 0;
}
(void)keySz;
return ret;
}
/* check that the private key is a pair for the public key in certificate
* return 1 (true) on match
* return 0 or negative value on failure/error
*
* key : buffer holding DER format key
* keySz : size of key buffer
* der : a initialized and parsed DecodedCert holding a certificate */
int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der)
{
if (key == NULL || der == NULL) {
return BAD_FUNC_ARG;
}
return wc_CheckPrivateKey(key, keySz, der->publicKey,
der->pubKeySize, (enum Key_Sum) der->keyOID);
}
#endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
#ifndef NO_PWDBASED

View File

@ -948,7 +948,7 @@ static void freeDecCertList(WC_DerCertList** list, byte** pkey, word32* pkeySz,
InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) {
if (wc_CheckPrivateKey(*pkey, *pkeySz, &DeCert) == 1) {
if (wc_CheckPrivateKeyCert(*pkey, *pkeySz, &DeCert) == 1) {
WOLFSSL_MSG("Key Pair found");
*cert = current->buffer;
*certSz = current->bufferSz;

View File

@ -1197,7 +1197,9 @@ WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
byte* serial, int* serialSz, word32 maxIdx);
WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
int maxIdx);
WOLFSSL_LOCAL int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der);
WOLFSSL_LOCAL int wc_CheckPrivateKeyCert(const byte* key, word32 keySz, DecodedCert* der);
WOLFSSL_LOCAL int wc_CheckPrivateKey(const byte* privKey, word32 privKeySz,
const byte* pubKey, word32 pubKeySz, enum Key_Sum ks);
WOLFSSL_LOCAL int StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g);
WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*);