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 else
#endif #endif
{ {
ret = wc_CheckPrivateKey(buff, size, der); ret = wc_CheckPrivateKeyCert(buff, size, der);
if (ret == 1) { if (ret == 1) {
ret = WOLFSSL_SUCCESS; ret = WOLFSSL_SUCCESS;
} }
@ -8034,7 +8034,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl)
} }
else else
#endif #endif
ret = wc_CheckPrivateKey(buff, size, &der); ret = wc_CheckPrivateKeyCert(buff, size, &der);
FreeDecodedCert(&der); FreeDecodedCert(&der);
return ret; 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 /* Use MD5 for hashing as OpenSSL uses a hash algorithm that is
* be good enough for database indexing */ * "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 wolfSSL_LH_strhash(const char *str)
{ {
unsigned long ret = 0; unsigned long ret = 0;
@ -42617,11 +42620,6 @@ err:
int wolfSSL_X509_check_private_key(WOLFSSL_X509 *x509, WOLFSSL_EVP_PKEY *key) 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"); WOLFSSL_ENTER("wolfSSL_X509_check_private_key");
if (!x509 || !key) { if (!x509 || !key) {
@ -42629,24 +42627,9 @@ err:
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
der = (byte*)wolfSSL_X509_get_der(x509, &derSz); return wc_CheckPrivateKey((byte*)key->pkey.ptr, key->pkey_sz,
if (der == NULL) { x509->pubKey.buffer, x509->pubKey.length,
WOLFSSL_MSG("wolfSSL_X509_get_der error"); x509->pubKeyOID) == 1 ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE;
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;
} }
/* wolfSSL uses negative values for error states. This function returns an /* 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 = X509_ATTRIBUTE_get0_type(attr, 0));
AssertNotNull(at->value.asn1_string); AssertNotNull(at->value.asn1_string);
AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "2xIE+qqp/rhyTXP+"); 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); AssertIntEQ(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), -1);
#endif
X509_free(req); X509_free(req);
BIO_free(bio); BIO_free(bio);
@ -38260,8 +38260,8 @@ static void test_wolfSSL_d2i_X509_REQ(void)
#ifdef OPENSSL_ALL #ifdef OPENSSL_ALL
X509_ATTRIBUTE* attr; X509_ATTRIBUTE* attr;
ASN1_TYPE *at; ASN1_TYPE *at;
#endif
STACK_OF(X509_EXTENSION) *exts = NULL; STACK_OF(X509_EXTENSION) *exts = NULL;
#endif
AssertNotNull(bio = BIO_new_file(csrExtFile, "rb")); AssertNotNull(bio = BIO_new_file(csrExtFile, "rb"));
/* This CSR contains an Extension Request attribute so /* This CSR contains an Extension Request attribute so
* we test extension parsing in a CSR attribute here. */ * 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); AssertIntEQ(X509_REQ_verify(req, pub_key), 1);
#ifdef OPENSSL_ALL
AssertNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(req)); AssertNotNull(exts = (STACK_OF(X509_EXTENSION)*)X509_REQ_get_extensions(req));
AssertIntEQ(sk_X509_EXTENSION_num(exts), 2); AssertIntEQ(sk_X509_EXTENSION_num(exts), 2);
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
#ifdef OPENSSL_ALL
/* /*
* Obtain the challenge password from the CSR * 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 = X509_ATTRIBUTE_get0_type(attr, 0));
AssertNotNull(at->value.asn1_string); AssertNotNull(at->value.asn1_string);
AssertStrEQ((char*)ASN1_STRING_data(at->value.asn1_string), "IGCu/xNL4/0/wOgo"); 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_key_usage, -1), 0);
AssertIntGE(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), 0); AssertIntGE(X509_get_ext_by_NID(req, NID_subject_alt_name, -1), 0);
#endif
X509_free(req); X509_free(req);
BIO_free(bio); BIO_free(bio);
EVP_PKEY_free(pub_key); EVP_PKEY_free(pub_key);
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
} }
#if !defined(NO_DSA) && !defined(HAVE_SELFTEST) #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 */ #endif /* HAVE_PKCS8 */
#if defined(HAVE_PKCS12) || !defined(NO_CHECK_PRIVATE_KEY) #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 1 (true) on match
* return 0 or negative value on failure/error * return 0 or negative value on failure/error
* *
* key : buffer holding DER format key * privKey : buffer holding DER format private key
* keySz : size of key buffer * privKeySz : size of private key buffer
* der : a initialized and parsed DecodedCert holding a certificate */ * pubKey : buffer holding DER format public key
int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) * 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; int ret;
(void)keySz; (void)privKeySz;
(void)pubKeySz;
if (key == NULL || der == NULL) { if (privKey == NULL || pubKey == NULL) {
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
#if !defined(NO_RSA) && !defined(NO_ASN_CRYPT) #if !defined(NO_RSA) && !defined(NO_ASN_CRYPT)
/* test if RSA key */ /* test if RSA key */
if (der->keyOID == RSAk) { if (ks == RSAk) {
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
RsaKey* a; RsaKey* a;
RsaKey* b = NULL; RsaKey* b = NULL;
@ -2957,12 +2961,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif #endif
return ret; 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"); WOLFSSL_MSG("Checking RSA key pair");
keyIdx = 0; /* reset to 0 for parsing public key */ keyIdx = 0; /* reset to 0 for parsing public key */
if ((ret = wc_RsaPublicKeyDecode(der->publicKey, &keyIdx, b, if ((ret = wc_RsaPublicKeyDecode(pubKey, &keyIdx, b,
der->pubKeySize)) == 0) { pubKeySz)) == 0) {
/* limit for user RSA crypto because of RsaKey /* limit for user RSA crypto because of RsaKey
* dereference. */ * dereference. */
#if defined(HAVE_USER_RSA) #if defined(HAVE_USER_RSA)
@ -2991,7 +2995,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif /* !NO_RSA && !NO_ASN_CRYPT */ #endif /* !NO_RSA && !NO_ASN_CRYPT */
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(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 #ifdef WOLFSSL_SMALL_STACK
ecc_key* key_pair; ecc_key* key_pair;
byte* privDer; byte* privDer;
@ -3021,8 +3025,8 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
return ret; return ret;
} }
if ((ret = wc_EccPrivateKeyDecode(key, &keyIdx, key_pair, if ((ret = wc_EccPrivateKeyDecode(privKey, &keyIdx, key_pair,
keySz)) == 0) { privKeySz)) == 0) {
WOLFSSL_MSG("Checking ECC key pair"); WOLFSSL_MSG("Checking ECC key pair");
if ((ret = wc_ecc_export_private_only(key_pair, privDer, &privSz)) 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); wc_ecc_free(key_pair);
ret = wc_ecc_init(key_pair); ret = wc_ecc_init(key_pair);
if (ret == 0) { if (ret == 0) {
ret = wc_ecc_import_private_key((const byte*)privDer, ret = wc_ecc_import_private_key(privDer,
privSz, (const byte*)der->publicKey, privSz, pubKey,
der->pubKeySize, key_pair); pubKeySz, key_pair);
} }
/* public and private extracted successfully now check if is /* 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 */ #endif /* HAVE_ECC && HAVE_ECC_KEY_EXPORT && !NO_ASN_CRYPT */
#if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT) #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT)
if (der->keyOID == ED25519k) { if (ks == ED25519k) {
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
ed25519_key* key_pair; ed25519_key* key_pair;
#else #else
@ -3077,12 +3081,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif #endif
return ret; return ret;
} }
if ((ret = wc_Ed25519PrivateKeyDecode(key, &keyIdx, key_pair, if ((ret = wc_Ed25519PrivateKeyDecode(privKey, &keyIdx, key_pair,
keySz)) == 0) { privKeySz)) == 0) {
WOLFSSL_MSG("Checking ED25519 key pair"); WOLFSSL_MSG("Checking ED25519 key pair");
keyIdx = 0; keyIdx = 0;
if ((ret = wc_ed25519_import_public(der->publicKey, der->pubKeySize, if ((ret = wc_ed25519_import_public(pubKey, pubKeySz,
key_pair)) == 0) { key_pair)) == 0) {
/* public and private extracted successfully no check if is /* public and private extracted successfully no check if is
* a pair and also do sanity checks on key. wc_ecc_check_key * a pair and also do sanity checks on key. wc_ecc_check_key
* checks that private * base generator equals pubkey */ * 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 */ #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */
#if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT) #if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT)
if (der->keyOID == ED448k) { if (ks == ED448k) {
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
ed448_key* key_pair = NULL; ed448_key* key_pair = NULL;
#else #else
@ -3120,12 +3124,12 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
#endif #endif
return ret; return ret;
} }
if ((ret = wc_Ed448PrivateKeyDecode(key, &keyIdx, key_pair, if ((ret = wc_Ed448PrivateKeyDecode(privKey, &keyIdx, key_pair,
keySz)) == 0) { privKeySz)) == 0) {
WOLFSSL_MSG("Checking ED448 key pair"); WOLFSSL_MSG("Checking ED448 key pair");
keyIdx = 0; keyIdx = 0;
if ((ret = wc_ed448_import_public(der->publicKey, der->pubKeySize, if ((ret = wc_ed448_import_public(pubKey, pubKeySz,
key_pair)) == 0) { key_pair)) == 0) {
/* public and private extracted successfully no check if is /* public and private extracted successfully no check if is
* a pair and also do sanity checks on key. wc_ecc_check_key * a pair and also do sanity checks on key. wc_ecc_check_key
* checks that private * base generator equals pubkey */ * checks that private * base generator equals pubkey */
@ -3144,11 +3148,26 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der)
ret = 0; ret = 0;
} }
(void)keySz;
return ret; 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 */ #endif /* HAVE_PKCS12 || !NO_CHECK_PRIVATE_KEY */
#ifndef NO_PWDBASED #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); InitDecodedCert(&DeCert, current->buffer, current->bufferSz, heap);
if (ParseCertRelative(&DeCert, CERT_TYPE, NO_VERIFY, NULL) == 0) { 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"); WOLFSSL_MSG("Key Pair found");
*cert = current->buffer; *cert = current->buffer;
*certSz = current->bufferSz; *certSz = current->bufferSz;

View File

@ -1197,7 +1197,9 @@ WOLFSSL_LOCAL int GetSerialNumber(const byte* input, word32* inOutIdx,
byte* serial, int* serialSz, word32 maxIdx); byte* serial, int* serialSz, word32 maxIdx);
WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash, WOLFSSL_LOCAL int GetNameHash(const byte* source, word32* idx, byte* hash,
int maxIdx); 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 StoreDHparams(byte* out, word32* outLen, mp_int* p, mp_int* g);
WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*); WOLFSSL_LOCAL int FlattenAltNames( byte*, word32, const DNS_entry*);