Merge pull request #1866 from dgarske/openssl_leak_fix

Fix leaks in compatibility functions `wolfSSL_X509_print` and `wolfSSL_i2d_RSAPublicKey`
This commit is contained in:
toddouska
2018-10-08 09:38:26 -07:00
committed by GitHub

111
src/ssl.c
View File

@@ -16436,13 +16436,13 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
if (wolfSSL_BIO_write(bio, "Certificate:\n", sizeof("Certificate:\n")) if (wolfSSL_BIO_write(bio, "Certificate:\n",
<= 0) { sizeof("Certificate:\n")) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
if (wolfSSL_BIO_write(bio, " Data:\n", sizeof(" Data:\n")) if (wolfSSL_BIO_write(bio, " Data:\n",
<= 0) { sizeof(" Data:\n")) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@@ -16498,7 +16498,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
/* serial is larger than int size so print off hex values */ /* serial is larger than int size so print off hex values */
if (wolfSSL_BIO_write(bio, "\n ", if (wolfSSL_BIO_write(bio, "\n ",
sizeof("\n ")) <= 0) { sizeof("\n ")) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
tmp[0] = '\0'; tmp[0] = '\0';
@@ -16653,7 +16653,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
/* get and print public key */ /* get and print public key */
if (wolfSSL_BIO_write(bio, "\n Subject Public Key Info:\n", if (wolfSSL_BIO_write(bio, "\n Subject Public Key Info:\n",
sizeof("\n Subject Public Key Info:\n")) <= 0) { sizeof("\n Subject Public Key Info:\n")) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
{ {
@@ -16664,13 +16664,13 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
case RSAk: case RSAk:
if (wolfSSL_BIO_write(bio, if (wolfSSL_BIO_write(bio,
" Public Key Algorithm: RSA\n", " Public Key Algorithm: RSA\n",
sizeof(" Public Key Algorithm: RSA\n")) <= 0) { sizeof(" Public Key Algorithm: RSA\n")) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
#ifdef HAVE_USER_RSA #ifdef HAVE_USER_RSA
if (wolfSSL_BIO_write(bio, if (wolfSSL_BIO_write(bio,
" Build without user RSA to print key\n", " Build without user RSA to print key\n",
sizeof(" Build without user RSA to print key\n")) sizeof(" Build without user RSA to print key\n"))
<= 0) { <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@@ -16690,17 +16690,21 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
if (wc_RsaPublicKeyDecode(x509->pubKey.buffer, if (wc_RsaPublicKeyDecode(x509->pubKey.buffer,
&idx, &rsa, x509->pubKey.length) != 0) { &idx, &rsa, x509->pubKey.length) != 0) {
WOLFSSL_MSG("Error decoding RSA key"); WOLFSSL_MSG("Error decoding RSA key");
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
if ((sz = wc_RsaEncryptSize(&rsa)) < 0) { if ((sz = wc_RsaEncryptSize(&rsa)) < 0) {
WOLFSSL_MSG("Error getting RSA key size"); WOLFSSL_MSG("Error getting RSA key size");
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n", XSNPRINTF(tmp, sizeof(tmp) - 1, "%s%s: (%d bit)\n%s\n",
" ", "Public-Key", 8 * sz, " ", "Public-Key", 8 * sz,
" Modulus:"); " Modulus:");
tmp[sizeof(tmp) - 1] = '\0'; tmp[sizeof(tmp) - 1] = '\0';
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { if (wolfSSL_BIO_write(bio, tmp,
(int)XSTRLEN(tmp)) <= 0) {
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@@ -16717,6 +16721,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
DYNAMIC_TYPE_TMP_BUFFER); DYNAMIC_TYPE_TMP_BUFFER);
if (rawKey == NULL) { if (rawKey == NULL) {
WOLFSSL_MSG("Memory error"); WOLFSSL_MSG("Memory error");
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
mp_to_unsigned_bin(&rsa.n, rawKey); mp_to_unsigned_bin(&rsa.n, rawKey);
@@ -16729,9 +16734,11 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
} }
else if ((idx != 0) && (((idx + lbit) % 15) == 0)) { else if ((idx != 0) && (((idx + lbit) % 15) == 0)) {
tmp[sizeof(tmp) - 1] = '\0'; tmp[sizeof(tmp) - 1] = '\0';
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) if (wolfSSL_BIO_write(bio, tmp,
<= 0) { (int)XSTRLEN(tmp)) <= 0) {
XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rawKey, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XSNPRINTF(tmp, sizeof(tmp) - 1, XSNPRINTF(tmp, sizeof(tmp) - 1,
@@ -16747,17 +16754,18 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
/* print out remaning modulus values */ /* print out remaning modulus values */
if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) { if ((idx > 0) && (((idx - 1 + lbit) % 15) != 0)) {
tmp[sizeof(tmp) - 1] = '\0'; tmp[sizeof(tmp) - 1] = '\0';
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) if (wolfSSL_BIO_write(bio, tmp,
<= 0) { (int)XSTRLEN(tmp)) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
} }
/* print out exponent values */ /* print out exponent values */
rawLen = mp_unsigned_bin_size(&rsa.e); rawLen = mp_unsigned_bin_size(&rsa.e);
if (rawLen < 0) { if (rawLen < 0) {
WOLFSSL_MSG("Error getting exponent size"); WOLFSSL_MSG("Error getting exponent size");
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@@ -16768,6 +16776,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
DYNAMIC_TYPE_TMP_BUFFER); DYNAMIC_TYPE_TMP_BUFFER);
if (rawKey == NULL) { if (rawKey == NULL) {
WOLFSSL_MSG("Memory error"); WOLFSSL_MSG("Memory error");
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XMEMSET(rawKey, 0, rawLen); XMEMSET(rawKey, 0, rawLen);
@@ -16776,12 +16785,15 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
idx = *(word32*)rawKey; idx = *(word32*)rawKey;
} }
XSNPRINTF(tmp, sizeof(tmp) - 1, XSNPRINTF(tmp, sizeof(tmp) - 1,
"\n Exponent: %d\n", idx); "\n Exponent: %d\n", idx);
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { if (wolfSSL_BIO_write(bio, tmp,
(int)XSTRLEN(tmp)) <= 0) {
XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wc_FreeRsaKey(&rsa);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rawKey, NULL, DYNAMIC_TYPE_TMP_BUFFER);
wc_FreeRsaKey(&rsa);
} }
#endif /* HAVE_USER_RSA */ #endif /* HAVE_USER_RSA */
break; break;
@@ -16795,7 +16807,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
if (wolfSSL_BIO_write(bio, if (wolfSSL_BIO_write(bio,
" Public Key Algorithm: EC\n", " Public Key Algorithm: EC\n",
sizeof(" Public Key Algorithm: EC\n")) <= 0) { sizeof(" Public Key Algorithm: EC\n")) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
if (wc_ecc_init_ex(&ecc, x509->heap, INVALID_DEVID) if (wc_ecc_init_ex(&ecc, x509->heap, INVALID_DEVID)
@@ -16814,7 +16826,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
8 * wc_ecc_size(&ecc), 8 * wc_ecc_size(&ecc),
" pub:"); " pub:");
tmp[sizeof(tmp) - 1] = '\0'; tmp[sizeof(tmp) - 1] = '\0';
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { if (wolfSSL_BIO_write(bio, tmp,
(int)XSTRLEN(tmp)) <= 0) {
wc_ecc_free(&ecc); wc_ecc_free(&ecc);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@@ -16865,8 +16878,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
/* print out remaning modulus values */ /* print out remaning modulus values */
if ((i > 0) && (((i - 1) % 15) != 0)) { if ((i > 0) && (((i - 1) % 15) != 0)) {
tmp[sizeof(tmp) - 1] = '\0'; tmp[sizeof(tmp) - 1] = '\0';
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) if (wolfSSL_BIO_write(bio, tmp,
<= 0) { (int)XSTRLEN(tmp)) <= 0) {
wc_ecc_free(&ecc); wc_ecc_free(&ecc);
XFREE(der, x509->heap, XFREE(der, x509->heap,
DYNAMIC_TYPE_TMP_BUFFER); DYNAMIC_TYPE_TMP_BUFFER);
@@ -16879,7 +16892,8 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s%s: %s\n", XSNPRINTF(tmp, sizeof(tmp) - 1, "\n%s%s: %s\n",
" ", "ASN1 OID", " ", "ASN1 OID",
ecc.dp->name); ecc.dp->name);
if (wolfSSL_BIO_write(bio, tmp, (int)XSTRLEN(tmp)) <= 0) { if (wolfSSL_BIO_write(bio, tmp,
(int)XSTRLEN(tmp)) <= 0) {
wc_ecc_free(&ecc); wc_ecc_free(&ecc);
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
@@ -16973,7 +16987,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
wolfSSL_X509_get_issuer_name(x509), buff, issSz); wolfSSL_X509_get_issuer_name(x509), buff, issSz);
if (wolfSSL_BIO_write(bio, "\n DirName:", if (wolfSSL_BIO_write(bio, "\n DirName:",
sizeof("\n DirName:")) <= 0) { sizeof("\n DirName:")) <= 0) {
#ifdef WOLFSSL_SMALL_STACK #ifdef WOLFSSL_SMALL_STACK
XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL); XFREE(issuer, NULL, DYNAMIC_TYPE_OPENSSL);
#endif #endif
@@ -17024,7 +17038,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509)
if (wolfSSL_BIO_write(bio, if (wolfSSL_BIO_write(bio,
" Signature Algorithm: ", " Signature Algorithm: ",
sizeof(" Signature Algorithm: ")) <= 0) { sizeof(" Signature Algorithm: ")) <= 0) {
return WOLFSSL_FAILURE; return WOLFSSL_FAILURE;
} }
XSNPRINTF(tmp, sizeof(tmp) - 1,"%s\n", GetSigName(sigOid)); XSNPRINTF(tmp, sizeof(tmp) - 1,"%s\n", GetSigName(sigOid));
@@ -23727,7 +23741,7 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void)
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
/* when calling SetIndividualExternal, mpi should be cleared by caller if no /* when calling SetIndividualExternal, mpi should be cleared by caller if no
* longer used. ie mp_clear(mpi). This is to free data when fastmath is * longer used. ie mp_free(mpi). This is to free data when fastmath is
* disabled since a copy of mpi is made by this function and placed into bn. * disabled since a copy of mpi is made by this function and placed into bn.
*/ */
static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi) static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
@@ -23763,6 +23777,10 @@ static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, mp_int* mpi)
#endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */
#ifdef OPENSSL_EXTRA /* only without X509_SMALL */ #ifdef OPENSSL_EXTRA /* only without X509_SMALL */
/* when calling SetIndividualInternal, mpi should be cleared by caller if no
* longer used. ie mp_free(mpi). This is to free data when fastmath is
* disabled since a copy of mpi is made by this function and placed into bn.
*/
static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi) static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, mp_int* mpi)
{ {
WOLFSSL_MSG("Entering SetIndividualInternal"); WOLFSSL_MSG("Entering SetIndividualInternal");
@@ -28392,34 +28410,36 @@ int wolfSSL_PEM_write_RSA_PUBKEY(XFILE fp, WOLFSSL_RSA *x)
#endif /* NO_FILESYSTEM */ #endif /* NO_FILESYSTEM */
WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp, long len) WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **r, const unsigned char **pp,
long len)
{ {
WOLFSSL_RSA *rsa = NULL; WOLFSSL_RSA *rsa = NULL;
WOLFSSL_ENTER("d2i_RSAPublicKey"); WOLFSSL_ENTER("d2i_RSAPublicKey");
if(pp == NULL){ if (pp == NULL) {
WOLFSSL_MSG("Bad argument"); WOLFSSL_MSG("Bad argument");
return NULL; return NULL;
} }
if((rsa = wolfSSL_RSA_new()) == NULL){ if ((rsa = wolfSSL_RSA_new()) == NULL) {
WOLFSSL_MSG("RSA_new failed"); WOLFSSL_MSG("RSA_new failed");
return NULL; return NULL;
} }
if(wolfSSL_RSA_LoadDer_ex(rsa, *pp, (int)len, WOLFSSL_RSA_LOAD_PUBLIC) if (wolfSSL_RSA_LoadDer_ex(rsa, *pp, (int)len, WOLFSSL_RSA_LOAD_PUBLIC)
!= WOLFSSL_SUCCESS){ != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("RSA_LoadDer failed"); WOLFSSL_MSG("RSA_LoadDer failed");
wolfSSL_RSA_free(rsa); wolfSSL_RSA_free(rsa);
rsa = NULL; rsa = NULL;
} }
if(r != NULL) if (r != NULL)
*r = rsa; *r = rsa;
return rsa; return rsa;
} }
/* Converts an rsa private key from der format to an rsa structure. /* Converts an RSA private key from DER format to an RSA structure.
Returns pointer to the rsa structure on succcess and NULL if error. */ Returns pointer to the RSA structure on success and NULL if error. */
WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r, WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r,
const unsigned char **derBuf, long derSz) const unsigned char **derBuf, long derSz)
{ {
@@ -28443,15 +28463,15 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r,
wolfSSL_RSA_free(rsa); wolfSSL_RSA_free(rsa);
rsa = NULL; rsa = NULL;
} }
if(r != NULL) if (r != NULL)
*r = rsa; *r = rsa;
return rsa; return rsa;
} }
#if !defined(HAVE_FAST_RSA) #if !defined(HAVE_FAST_RSA)
/* Converts an internal rsa structure to der format. /* Converts an internal RSA structure to DER format.
Returns size of der on success and WOLFSSL_FAILURE if error */ Returns size of DER on success and WOLFSSL_FAILURE if error */
int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp)
{ {
#if defined(WOLFSSL_KEY_GEN) #if defined(WOLFSSL_KEY_GEN)
@@ -28494,14 +28514,14 @@ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp)
return ret; return ret;
} }
/* ret is the size of the der buffer */ /* ret is the size of the DER buffer */
for (i = 0; i < ret; i++) { for (i = 0; i < ret; i++) {
*(*pp + i) = *(der + i); *(*pp + i) = *(der + i);
} }
*pp += ret; *pp += ret;
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return ret; /* returns size of der if successful */ return ret; /* returns size of DER if successful */
#else #else
(void)rsa; (void)rsa;
(void)pp; (void)pp;
@@ -28520,9 +28540,12 @@ int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, const unsigned char **pp)
WOLFSSL_ENTER("i2d_RSAPublicKey"); WOLFSSL_ENTER("i2d_RSAPublicKey");
if (rsa == NULL) if (rsa == NULL)
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("SetRsaInternal Failed"); if (rsa->inSet == 0) {
return ret; if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) {
WOLFSSL_MSG("SetRsaInternal Failed");
return ret;
}
} }
if ((derLen = RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0) if ((derLen = RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0)
return WOLFSSL_FATAL_ERROR; return WOLFSSL_FATAL_ERROR;
@@ -28536,7 +28559,7 @@ int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, const unsigned char **pp)
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return ret; return ret;
} }
if((pp != NULL) && (ret >= 0)) if ((pp != NULL) && (ret >= 0))
*pp = der; *pp = der;
else else
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);