Skip to content

Commit ad8b6db

Browse files
Merge pull request #10217 from ColtonWilley/null-checks-evp-ocsp-x509
Fix NULL derefs, buffer overflow, and i2d contract in EVP/OCSP/X509
2 parents a0bfcbb + 7bf63e9 commit ad8b6db

File tree

6 files changed

+93
-22
lines changed

6 files changed

+93
-22
lines changed

src/ocsp.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,9 @@ int wolfSSL_OCSP_resp_find_status(WOLFSSL_OCSP_BASICRESP *bs,
749749

750750
single = bs->single;
751751
while (single != NULL) {
752-
if ((XMEMCMP(single->status->serial, id->status->serial, (size_t)single->status->serialSz) == 0)
752+
if (single->status != NULL && id->status != NULL &&
753+
(XMEMCMP(single->status->serial, id->status->serial,
754+
(size_t)single->status->serialSz) == 0)
753755
&& (XMEMCMP(single->issuerHash, id->issuerHash, OCSP_DIGEST_SIZE) == 0)
754756
&& (XMEMCMP(single->issuerKeyHash, id->issuerKeyHash, OCSP_DIGEST_SIZE) == 0)) {
755757
break;
@@ -1108,6 +1110,9 @@ int wolfSSL_OCSP_basic_verify(WOLFSSL_OCSP_BASICRESP* bs,
11081110
int embedded;
11091111
DecodedCert *cert = NULL;
11101112

1113+
if (bs == NULL)
1114+
return WOLFSSL_FAILURE;
1115+
11111116
ret = OcspFindSigner(bs, certs, &cert, &embedded, flags);
11121117
if (ret != 0) {
11131118
WOLFSSL_MSG("OCSP no signer found");
@@ -1300,15 +1305,31 @@ int wolfSSL_i2d_OCSP_RESPONSE(OcspResponse* response,
13001305
if (response == NULL)
13011306
return BAD_FUNC_ARG;
13021307

1308+
if (response->source == NULL)
1309+
return BAD_FUNC_ARG;
1310+
13031311
if (data == NULL)
13041312
return (int)response->maxIdx;
13051313

1306-
XMEMCPY(*data, response->source, response->maxIdx);
1314+
if (*data == NULL) {
1315+
*data = (unsigned char*)XMALLOC(response->maxIdx, NULL,
1316+
DYNAMIC_TYPE_OPENSSL);
1317+
if (*data == NULL)
1318+
return -1;
1319+
XMEMCPY(*data, response->source, response->maxIdx);
1320+
}
1321+
else {
1322+
XMEMCPY(*data, response->source, response->maxIdx);
1323+
*data += response->maxIdx;
1324+
}
1325+
13071326
return (int)response->maxIdx;
13081327
}
13091328

13101329
int wolfSSL_OCSP_response_status(OcspResponse *response)
13111330
{
1331+
if (response == NULL)
1332+
return -1;
13121333
return response->responseStatus;
13131334
}
13141335

@@ -1335,8 +1356,12 @@ const char *wolfSSL_OCSP_response_status_str(long s)
13351356
WOLFSSL_OCSP_BASICRESP* wolfSSL_OCSP_response_get1_basic(OcspResponse* response)
13361357
{
13371358
WOLFSSL_OCSP_BASICRESP* bs;
1338-
const unsigned char *ptr = response->source;
1359+
const unsigned char *ptr;
13391360

1361+
if (response == NULL || response->source == NULL)
1362+
return NULL;
1363+
1364+
ptr = response->source;
13401365
bs = wolfSSL_d2i_OCSP_RESPONSE(NULL, &ptr, response->maxIdx);
13411366
return bs;
13421367
}
@@ -1637,8 +1662,8 @@ int wolfSSL_OCSP_single_get0_status(WOLFSSL_OCSP_SINGLERESP *single,
16371662
WOLFSSL_ASN1_TIME **thisupd,
16381663
WOLFSSL_ASN1_TIME **nextupd)
16391664
{
1640-
if (single == NULL)
1641-
return WOLFSSL_FAILURE;
1665+
if (single == NULL || single->status == NULL)
1666+
return -1;
16421667

16431668
#ifdef WOLFSSL_OCSP_PARSE_STATUS
16441669
if (thisupd != NULL)
@@ -1784,7 +1809,7 @@ int wolfSSL_OCSP_REQ_CTX_add1_header(WOLFSSL_OCSP_REQ_CTX *ctx,
17841809
{
17851810
WOLFSSL_ENTER("wolfSSL_OCSP_REQ_CTX_add1_header");
17861811

1787-
if (name == NULL) {
1812+
if (ctx == NULL || name == NULL) {
17881813
WOLFSSL_MSG("Bad parameter");
17891814
return WOLFSSL_FAILURE;
17901815
}

src/ssl.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11720,13 +11720,19 @@ char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER* cipher, char* in,
1172011720
int wolfSSL_OCSP_parse_url(const char* url, char** host, char** port,
1172111721
char** path, int* ssl)
1172211722
{
11723-
const char* u = url;
11723+
const char* u;
1172411724
const char* upath; /* path in u */
1172511725
const char* uport; /* port in u */
1172611726
const char* hostEnd;
1172711727

1172811728
WOLFSSL_ENTER("OCSP_parse_url");
1172911729

11730+
if (url == NULL || host == NULL || port == NULL || path == NULL ||
11731+
ssl == NULL) {
11732+
return WOLFSSL_FAILURE;
11733+
}
11734+
11735+
u = url;
1173011736
*host = NULL;
1173111737
*port = NULL;
1173211738
*path = NULL;

src/x509.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,7 +1317,9 @@ int wolfSSL_X509_add_ext(WOLFSSL_X509 *x509, WOLFSSL_X509_EXTENSION *ext,
13171317
if (ext && ext->value.data) {
13181318
if (ext->value.length == sizeof(word16)) {
13191319
/* if ext->value is already word16, set directly */
1320-
x509->keyUsage = *(word16*)ext->value.data;
1320+
word16 ku;
1321+
XMEMCPY(&ku, ext->value.data, sizeof(word16));
1322+
x509->keyUsage = ku;
13211323
#ifdef BIG_ENDIAN_ORDER
13221324
x509->keyUsage = rotlFixed16(x509->keyUsage, 8U);
13231325
#endif
@@ -10998,6 +11000,11 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509)
1099811000
if (x509->serialNumber != NULL)
1099911001
return x509->serialNumber;
1100011002

11003+
if (x509->serialSz < 0) {
11004+
WOLFSSL_MSG("Invalid serial number size");
11005+
return NULL;
11006+
}
11007+
1100111008
a = wolfSSL_ASN1_INTEGER_new();
1100211009
if (a == NULL)
1100311010
return NULL;
@@ -16134,7 +16141,8 @@ int wolfSSL_X509_set1_notBefore(WOLFSSL_X509* x509, const WOLFSSL_ASN1_TIME *t)
1613416141
int wolfSSL_X509_set_serialNumber(WOLFSSL_X509* x509, WOLFSSL_ASN1_INTEGER* s)
1613516142
{
1613616143
WOLFSSL_ENTER("wolfSSL_X509_set_serialNumber");
16137-
if (x509 == NULL || s == NULL || s->length >= EXTERNAL_SERIAL_SIZE)
16144+
if (x509 == NULL || s == NULL || s->data == NULL ||
16145+
s->length >= EXTERNAL_SERIAL_SIZE)
1613816146
return WOLFSSL_FAILURE;
1613916147

1614016148
/* WOLFSSL_ASN1_INTEGER has type | size | data

tests/api.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20492,7 +20492,7 @@ static int test_wolfSSL_OCSP_single_get0_status(void)
2049220492
ExpectPtrEq(nextDate, &certStatus.nextDateParsed);
2049320493

2049420494
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(NULL, NULL, NULL, NULL, NULL),
20495-
CERT_GOOD);
20495+
-1);
2049620496
ExpectIntEQ(wolfSSL_OCSP_single_get0_status(&single, NULL, NULL, NULL,
2049720497
NULL), CERT_GOOD);
2049820498
#endif

wolfcrypt/src/evp.c

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,7 +1314,11 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
13141314
#ifndef WOLFSSL_AESGCM_STREAM
13151315
if ((ctx->authBuffer && ctx->authBufferLen > 0)
13161316
|| (ctx->authBufferLen == 0)) {
1317-
if (ctx->enc)
1317+
if (ctx->authBufferLen > 0 && out == NULL) {
1318+
ret = WOLFSSL_FAILURE;
1319+
*outl = 0;
1320+
}
1321+
else if (ctx->enc)
13181322
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out,
13191323
ctx->authBuffer, ctx->authBufferLen,
13201324
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
@@ -1397,7 +1401,11 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, unsigned char *out,
13971401
case WC_AES_256_CCM_TYPE:
13981402
if ((ctx->authBuffer && ctx->authBufferLen > 0)
13991403
|| (ctx->authBufferLen == 0)) {
1400-
if (ctx->enc) {
1404+
if (ctx->authBufferLen > 0 && out == NULL) {
1405+
ret = WOLFSSL_FAILURE;
1406+
*outl = 0;
1407+
}
1408+
else if (ctx->enc) {
14011409
ret = wc_AesCcmEncrypt(&ctx->cipher.aes, out,
14021410
ctx->authBuffer, (word32)ctx->authBufferLen,
14031411
ctx->iv, (word32)ctx->ivSz, ctx->authTag,
@@ -4309,16 +4317,16 @@ int wolfSSL_EVP_SignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sigret,
43094317
#ifndef NO_DSA
43104318
case WC_EVP_PKEY_DSA: {
43114319
int bytes;
4312-
ret = wolfSSL_DSA_do_sign(md, sigret, pkey->dsa);
4313-
/* wolfSSL_DSA_do_sign() can return WOLFSSL_FATAL_ERROR */
4314-
if (ret != WOLFSSL_SUCCESS)
4315-
return ret;
43164320
bytes = wolfSSL_BN_num_bytes(pkey->dsa->q);
43174321
if (bytes == WC_NO_ERR_TRACE(WOLFSSL_FAILURE) ||
4318-
(int)*siglen < bytes * 2)
4322+
bytes * 2 > (int)*siglen)
43194323
{
43204324
return WOLFSSL_FAILURE;
43214325
}
4326+
ret = wolfSSL_DSA_do_sign(md, sigret, pkey->dsa);
4327+
/* wolfSSL_DSA_do_sign() can return WOLFSSL_FATAL_ERROR */
4328+
if (ret != WOLFSSL_SUCCESS)
4329+
return ret;
43224330
*siglen = (unsigned int)(bytes * 2);
43234331
return WOLFSSL_SUCCESS;
43244332
}
@@ -4398,7 +4406,8 @@ int wolfSSL_EVP_VerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
43984406
unsigned char md[WC_MAX_DIGEST_SIZE];
43994407
unsigned int mdsize;
44004408

4401-
if (ctx == NULL) return WOLFSSL_FAILURE;
4409+
if (ctx == NULL || pkey == NULL || sig == NULL)
4410+
return WOLFSSL_FAILURE;
44024411
WOLFSSL_ENTER("EVP_VerifyFinal");
44034412
ret = wolfSSL_EVP_DigestFinal(ctx, md, &mdsize);
44044413
if (ret <= 0)
@@ -4459,6 +4468,9 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKEY_new_mac_key(int type, WOLFSSL_ENGINE* e,
44594468
if (type != WC_EVP_PKEY_HMAC || (key == NULL && keylen != 0))
44604469
return NULL;
44614470

4471+
if (keylen < 0)
4472+
return NULL;
4473+
44624474
pkey = wolfSSL_EVP_PKEY_new();
44634475
if (pkey != NULL) {
44644476
pkey->pkey.ptr = (char*)XMALLOC((size_t)keylen, NULL,
@@ -4870,6 +4882,9 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig,
48704882
return WOLFSSL_SUCCESS;
48714883
}
48724884
}
4885+
else if (ctx->pctx == NULL || ctx->pctx->pkey == NULL) {
4886+
return WOLFSSL_FAILURE;
4887+
}
48734888
#ifndef NO_RSA
48744889
else if (ctx->pctx->pkey->type == WC_EVP_PKEY_RSA) {
48754890
if (sig == NULL) {
@@ -5006,6 +5021,8 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,
50065021
return WOLFSSL_FAILURE;
50075022
}
50085023
else {
5024+
if (ctx->pctx == NULL || ctx->pctx->pkey == NULL)
5025+
return WOLFSSL_FAILURE;
50095026
/* Verify the signature with the digest. */
50105027
switch (ctx->pctx->pkey->type) {
50115028
#if !defined(NO_RSA)
@@ -10232,6 +10249,9 @@ int wolfSSL_EVP_Digest(const unsigned char* in, int inSz, unsigned char* out,
1023210249
return WOLFSSL_FAILURE;
1023310250
}
1023410251

10252+
if (inSz < 0)
10253+
return WOLFSSL_FAILURE;
10254+
1023510255
err = wolfSSL_EVP_get_hashinfo(evp, &hashType, &hashSz);
1023610256
if (err != WOLFSSL_SUCCESS)
1023710257
return err;
@@ -11279,6 +11299,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
1127911299
enum wc_HashType macType;
1128011300

1128111301
WOLFSSL_ENTER("wolfSSL_EVP_DigestFinal");
11302+
1128211303
macType = EvpMd2MacType(wolfSSL_EVP_MD_CTX_md(ctx));
1128311304
switch (macType) {
1128411305
case WC_HASH_TYPE_MD4:
@@ -11304,16 +11325,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
1130411325

1130511326
case WC_HASH_TYPE_SHAKE128:
1130611327
#if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE128)
11307-
*s = 16; /* if mixing up XOF with plain digest 128 bit is
11308-
* default for SHAKE128 */
11328+
if (s != NULL)
11329+
*s = 16; /* if mixing up XOF with plain digest 128 bit is
11330+
* default for SHAKE128 */
1130911331
#else
1131011332
return WOLFSSL_FAILURE;
1131111333
#endif
1131211334
break;
1131311335
case WC_HASH_TYPE_SHAKE256:
1131411336
#if defined(WOLFSSL_SHA3) && defined(WOLFSSL_SHAKE256)
11315-
*s = 32; /* if mixing up XOF with plain digest 256 bit is
11316-
* default for SHAKE256 */
11337+
if (s != NULL)
11338+
*s = 32; /* if mixing up XOF with plain digest 256 bit is
11339+
* default for SHAKE256 */
1131711340
#else
1131811341
return WOLFSSL_FAILURE;
1131911342
#endif
@@ -12881,6 +12904,9 @@ int wolfSSL_EVP_EncodeBlock(unsigned char *out, const unsigned char *in,
1288112904
if (out == NULL || in == NULL)
1288212905
return WOLFSSL_FATAL_ERROR;
1288312906

12907+
if (inLen < 0)
12908+
return WOLFSSL_FATAL_ERROR;
12909+
1288412910
if (Base64_Encode_NoNl(in, (word32)inLen, out, &ret) == 0)
1288512911
return (int)ret;
1288612912
else
@@ -12897,6 +12923,9 @@ int wolfSSL_EVP_DecodeBlock(unsigned char *out, const unsigned char *in,
1289712923
if (out == NULL || in == NULL)
1289812924
return WOLFSSL_FATAL_ERROR;
1289912925

12926+
if (inLen < 0)
12927+
return WOLFSSL_FATAL_ERROR;
12928+
1290012929
if (Base64_Decode(in, (word32)inLen, out, &ret) == 0)
1290112930
return (int)ret;
1290212931
else

wolfcrypt/src/pwdbased.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ int wc_PBKDF1_ex(byte* key, int keyLen, byte* iv, int ivLen,
7676
return BAD_FUNC_ARG;
7777
}
7878

79+
if (keyLen > INT_MAX - ivLen)
80+
return BAD_FUNC_ARG;
81+
7982
if (iterations <= 0)
8083
iterations = 1;
8184

0 commit comments

Comments
 (0)