Improvements for XFTELL return code and MAX_WOLFSSL_FILE_SIZE checking.

Fixes #2527
This commit is contained in:
David Garske
2019-11-18 13:49:06 -08:00
parent c9f7741dfb
commit ca5549ae91
4 changed files with 151 additions and 103 deletions

View File

@@ -1332,7 +1332,12 @@ int wolfSSL_BIO_get_len(WOLFSSL_BIO *bio)
len = WOLFSSL_BAD_FILE;
}
if (len == 0) {
memSz = XFTELL(file) - curr;
memSz = XFTELL(file);
if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0)
len = WOLFSSL_BAD_FILE;
}
if (len == 0) {
memSz -= curr;
len = (int)memSz;
if (XFSEEK(file, curr, SEEK_SET) != 0)
len = WOLFSSL_BAD_FILE;
@@ -1590,4 +1595,3 @@ int wolfSSL_BIO_flush(WOLFSSL_BIO* bio)
return 1;
}
#endif /* WOLFSSL_BIO_INCLUDED */

View File

@@ -662,33 +662,34 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
}
#ifndef NO_FILESYSTEM
else if (bio->type == WOLFSSL_BIO_FILE) {
long i;
long l;
long fcur;
long flen;
if (bio->ptr == NULL)
return NULL;
i = XFTELL((XFILE)bio->ptr);
if (i < 0)
fcur = XFTELL((XFILE)bio->ptr);
if (fcur < 0)
return NULL;
if(XFSEEK((XFILE)bio->ptr, 0, SEEK_END) != 0)
return NULL;
l = XFTELL((XFILE)bio->ptr);
if (l < 0)
flen = XFTELL((XFILE)bio->ptr);
if (flen < 0)
return NULL;
if (XFSEEK((XFILE)bio->ptr, i, SEEK_SET) != 0)
if (XFSEEK((XFILE)bio->ptr, fcur, SEEK_SET) != 0)
return NULL;
/* check calculated length */
if (l - i <= 0)
fcur = flen - fcur;
if (fcur > MAX_WOLFSSL_FILE_SIZE || fcur <= 0)
return NULL;
data = (byte*)XMALLOC(l - i, 0, DYNAMIC_TYPE_TMP_BUFFER);
data = (byte*)XMALLOC(fcur, 0, DYNAMIC_TYPE_TMP_BUFFER);
if (data == NULL)
return NULL;
dataAlloced = 1;
len = wolfSSL_BIO_read(bio, (char *)data, (int)l);
len = wolfSSL_BIO_read(bio, (char *)data, (int)flen);
}
#endif
else
@@ -696,7 +697,8 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE_bio(WOLFSSL_BIO* bio,
if (len > 0) {
p = data;
ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p, len);
ret = wolfSSL_d2i_OCSP_RESPONSE(response, (const unsigned char **)&p,
len);
}
if (dataAlloced)
@@ -1086,4 +1088,3 @@ int wolfSSL_OCSP_check_nonce(OcspRequest* req, WOLFSSL_OCSP_BASICRESP* bs)
#endif /* HAVE_OCSP */
#endif /* WOLFCRYPT_ONLY */

View File

@@ -1376,6 +1376,10 @@ static int LoadKeyFile(byte** keyBuf, word32* keyBufSz,
return -1;
}
fileSz = XFTELL(file);
if (fileSz > MAX_WOLFSSL_FILE_SIZE || fileSz < 0) {
XFCLOSE(file);
return -1;
}
XREWIND(file);
loadBuf = (byte*)XMALLOC(fileSz, NULL, DYNAMIC_TYPE_FILE);

145
src/ssl.c
View File

@@ -6397,6 +6397,12 @@ int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
sz = XFTELL(file);
XREWIND(file);
if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
WOLFSSL_MSG("ProcessFile file size error");
XFCLOSE(file);
return WOLFSSL_BAD_FILE;
}
if (sz > (long)sizeof(staticBuffer)) {
WOLFSSL_MSG("Getting dynamic buffer");
myBuffer = (byte*)XMALLOC(sz, heapHint, DYNAMIC_TYPE_FILE);
@@ -6406,10 +6412,6 @@ int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
}
dynamic = 1;
}
else if (sz <= 0) {
XFCLOSE(file);
return WOLFSSL_BAD_FILE;
}
if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
ret = WOLFSSL_BAD_FILE;
@@ -6608,7 +6610,7 @@ int wolfSSL_CertManagerVerify(WOLFSSL_CERT_MANAGER* cm, const char* fname,
XREWIND(file);
if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
WOLFSSL_MSG("CertManagerVerify file bad size");
WOLFSSL_MSG("CertManagerVerify file size error");
XFCLOSE(file);
return WOLFSSL_BAD_FILE;
}
@@ -7077,6 +7079,12 @@ static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
sz = XFTELL(file);
XREWIND(file);
if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
WOLFSSL_MSG("SetTmpDH file size error");
XFCLOSE(file);
return WOLFSSL_BAD_FILE;
}
if (sz > (long)sizeof(staticBuffer)) {
WOLFSSL_MSG("Getting dynamic buffer");
myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
@@ -7086,10 +7094,6 @@ static int wolfSSL_SetTmpDH_file_wrapper(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
}
dynamic = 1;
}
else if (sz <= 0) {
XFCLOSE(file);
return WOLFSSL_BAD_FILE;
}
if ( (ret = (int)XFREAD(myBuffer, 1, sz, file)) != sz)
ret = WOLFSSL_BAD_FILE;
@@ -10596,8 +10600,8 @@ int CM_RestoreCertCache(WOLFSSL_CERT_MANAGER* cm, const char* fname)
memSz = (int)XFTELL(file);
XREWIND(file);
if (memSz <= 0) {
WOLFSSL_MSG("Bad file size");
if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz <= 0) {
WOLFSSL_MSG("CM_RestoreCertCache file size error");
XFCLOSE(file);
return WOLFSSL_BAD_FILE;
}
@@ -18963,8 +18967,8 @@ WOLFSSL_X509* wolfSSL_X509_d2i_fp(WOLFSSL_X509** x509, XFILE file)
sz = XFTELL(file);
XREWIND(file);
if (sz < 0) {
WOLFSSL_MSG("Bad tell on FILE");
if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
WOLFSSL_MSG("X509_d2i file size error");
return NULL;
}
@@ -19018,6 +19022,12 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
sz = XFTELL(file);
XREWIND(file);
if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
WOLFSSL_MSG("X509_load_certificate_file size error");
XFCLOSE(file);
return NULL;
}
if (sz > (long)sizeof(staticBuffer)) {
fileBuffer = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
if (fileBuffer == NULL) {
@@ -19026,10 +19036,6 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format)
}
dynamic = 1;
}
else if (sz < 0) {
XFCLOSE(file);
return NULL;
}
ret = (int)XFREAD(fileBuffer, 1, sz, file);
if (ret != sz) {
@@ -21737,8 +21743,10 @@ int wolfSSL_X509_LOOKUP_load_file(WOLFSSL_X509_LOOKUP* lookup,
sz = XFTELL(fp);
XREWIND(fp);
if (sz <= 0)
if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
WOLFSSL_MSG("X509_LOOKUP_load_file size error");
goto end;
}
pem = (byte*)XMALLOC(sz, 0, DYNAMIC_TYPE_PEM);
if (pem == NULL) {
@@ -22895,53 +22903,63 @@ static void *wolfSSL_d2i_X509_fp_ex(XFILE file, void **x509, int type)
{
void *newx509 = NULL;
byte *fileBuffer = NULL;
if (file != XBADFILE)
{
long sz = 0;
if(XFSEEK(file, 0, XSEEK_END) != 0)
/* init variable */
if (x509)
*x509 = NULL;
/* argument check */
if (file == XBADFILE) {
return NULL;
}
/* determine file size */
if (XFSEEK(file, 0, XSEEK_END) != 0) {
return NULL;
}
sz = XFTELL(file);
XREWIND(file);
if (sz < 0)
{
WOLFSSL_MSG("Bad tell on FILE");
if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0) {
WOLFSSL_MSG("d2i_X509_fp_ex file size error");
return NULL;
}
fileBuffer = (byte *)XMALLOC(sz, NULL, DYNAMIC_TYPE_FILE);
if (fileBuffer != NULL)
{
if((long)XFREAD(fileBuffer, 1, sz, file) != sz)
{
if (fileBuffer != NULL) {
if ((long)XFREAD(fileBuffer, 1, sz, file) != sz) {
WOLFSSL_MSG("File read failed");
goto err_exit;
}
if(type == CERT_TYPE)
if (type == CERT_TYPE) {
newx509 = (void *)wolfSSL_X509_d2i(NULL, fileBuffer, (int)sz);
}
#ifdef HAVE_CRL
else if(type == CRL_TYPE)
else if (type == CRL_TYPE) {
newx509 = (void *)wolfSSL_d2i_X509_CRL(NULL, fileBuffer, (int)sz);
}
#endif
#if !defined(NO_ASN) && !defined(NO_PWDBASED)
else if (type == PKCS12_TYPE) {
if((newx509 = wc_PKCS12_new()) == NULL)
goto err_exit;
if(wc_d2i_PKCS12(fileBuffer, (int)sz, (WC_PKCS12*)newx509) < 0)
if ((newx509 = wc_PKCS12_new()) == NULL) {
goto err_exit;
}
if (wc_d2i_PKCS12(fileBuffer, (int)sz, (WC_PKCS12*)newx509) < 0) {
goto err_exit;
}
}
#endif
else goto err_exit;
if(newx509 == NULL)
{
else {
goto err_exit;
}
if (newx509 == NULL) {
WOLFSSL_MSG("X509 failed");
goto err_exit;
}
}
}
if (x509 != NULL)
if (x509)
*x509 = newx509;
goto _exit;
@@ -22955,6 +22973,7 @@ err_exit:
_exit:
if (fileBuffer != NULL)
XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE);
return newx509;
}
@@ -27057,13 +27076,18 @@ int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname)
sz = XFTELL(file);
XREWIND(file);
if (sz > MAX_WOLFSSL_FILE_SIZE || sz < 0) {
WOLFSSL_MSG("cmp_peer_cert_to_file size error");
XFCLOSE(file);
return WOLFSSL_BAD_FILE;
}
if (sz > (long)sizeof(staticBuffer)) {
WOLFSSL_MSG("Getting dynamic buffer");
myBuffer = (byte*)XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE);
dynamic = 1;
}
if ((myBuffer != NULL) &&
(sz > 0) &&
(XFREAD(myBuffer, 1, sz, file) == sz) &&
@@ -35025,10 +35049,16 @@ err:
if (XFSEEK(fp, i, SEEK_SET) != 0)
return NULL;
pemSz = (int)(l - i);
/* check calculated length */
if (pemSz < 0)
if (pemSz > MAX_WOLFSSL_FILE_SIZE || pemSz < 0) {
WOLFSSL_MSG("PEM_read_X509_ex file size error");
return NULL;
if((pem = (unsigned char*)XMALLOC(pemSz, 0, DYNAMIC_TYPE_PEM)) == NULL)
}
/* allocate pem buffer */
pem = (unsigned char*)XMALLOC(pemSz, NULL, DYNAMIC_TYPE_PEM);
if (pem == NULL)
return NULL;
if ((int)XFREAD((char *)pem, 1, pemSz, fp) != pemSz)
@@ -35036,21 +35066,21 @@ err:
switch (type) {
case CERT_TYPE:
newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem, pemSz,
WOLFSSL_FILETYPE_PEM);
newx509 = (void *)wolfSSL_X509_load_certificate_buffer(pem,
pemSz, WOLFSSL_FILETYPE_PEM);
break;
#ifdef HAVE_CRL
case CRL_TYPE:
{
if ((PemToDer(pem, pemSz, CRL_TYPE, &der, NULL, NULL, NULL)) < 0)
goto err_exit;
derSz = der->length;
if((newx509 = (void *)wolfSSL_d2i_X509_CRL(
(WOLFSSL_X509_CRL **)x, (const unsigned char *)der->buffer, derSz)) == NULL)
newx509 = (void*)wolfSSL_d2i_X509_CRL((WOLFSSL_X509_CRL **)x,
(const unsigned char *)der->buffer, derSz);
if (newx509 == NULL)
goto err_exit;
FreeDer(&der);
break;
}
#endif
default:
@@ -35059,20 +35089,21 @@ err:
if (x != NULL) {
*x = newx509;
}
XFREE(pem, 0, DYNAMIC_TYPE_PEM);
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
return newx509;
err_exit:
if (pem != NULL)
XFREE(pem, 0, DYNAMIC_TYPE_PEM);
XFREE(pem, NULL, DYNAMIC_TYPE_PEM);
if (der != NULL)
FreeDer(&der);
return NULL;
/* unused */
(void)cb;
(void)u;
(void)derSz;
return NULL;
}
WOLFSSL_API WOLFSSL_X509* wolfSSL_PEM_read_X509(XFILE fp, WOLFSSL_X509 **x,
@@ -37687,8 +37718,10 @@ WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bio, WOLFSSL_DH **x,
sz = XFTELL((XFILE)bio->ptr);
if (XFSEEK((XFILE)bio->ptr, 0, SEEK_SET) != 0)
goto end;
if (sz <= 0L)
if (sz > MAX_WOLFSSL_FILE_SIZE || sz <= 0L) {
WOLFSSL_MSG("PEM_read_bio_DHparams file size error");
goto end;
}
mem = (unsigned char*)XMALLOC(sz, NULL, DYNAMIC_TYPE_PEM);
if (mem == NULL)
goto end;
@@ -44361,7 +44394,13 @@ static int bio_get_data(WOLFSSL_BIO* bio, byte** data)
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
memSz = XFTELL(file) - curr;
memSz = XFTELL(file);
if (memSz > MAX_WOLFSSL_FILE_SIZE || memSz < 0) {
ret = WOLFSSL_BAD_FILE;
}
}
if (ret == 0) {
memSz -= curr;
ret = (int)memSz;
if (XFSEEK(file, curr, SEEK_SET) != 0)
ret = WOLFSSL_BAD_FILE;