Skip to content

Commit 2264212

Browse files
committed
Add negative length validation to d2i wrappers, PEM helpers, and buffer loaders
Reject negative signed lengths before they are cast to unsigned (word32/size_t), preventing heap buffer over-reads and oversized allocations. Covers d2i_* OpenSSL compat wrappers, ProcessBuffer, PemToDer, certgen helpers, and CRL buffer paths.
1 parent 5074cf3 commit 2264212

9 files changed

Lines changed: 71 additions & 12 deletions

File tree

src/crl.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -849,7 +849,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type,
849849

850850
WOLFSSL_ENTER("BufferLoadCRL");
851851

852-
if (crl == NULL || buff == NULL || sz == 0)
852+
if (crl == NULL || buff == NULL || sz <= 0)
853853
return BAD_FUNC_ARG;
854854

855855
if (type == WOLFSSL_FILETYPE_PEM) {
@@ -1175,7 +1175,7 @@ int GetCRLInfo(WOLFSSL_CRL* crl, CrlInfo* info, const byte* buff,
11751175

11761176
WOLFSSL_ENTER("GetCRLInfo");
11771177

1178-
if (crl == NULL || info == NULL || buff == NULL || sz == 0)
1178+
if (crl == NULL || info == NULL || buff == NULL || sz <= 0)
11791179
return BAD_FUNC_ARG;
11801180

11811181
if (type == WOLFSSL_FILETYPE_PEM) {

src/ocsp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,8 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response,
12441244

12451245
if (data == NULL)
12461246
return NULL;
1247+
if (len <= 0)
1248+
return NULL;
12471249

12481250
if (response != NULL)
12491251
resp = *response;

src/pk_ec.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group,
450450

451451
if (in_pp == NULL || *in_pp == NULL)
452452
return NULL;
453+
if (inSz <= 0)
454+
return NULL;
453455

454456
in = *in_pp;
455457

@@ -4981,6 +4983,9 @@ WOLFSSL_ECDSA_SIG* wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG** sig,
49814983
if (pp == NULL) {
49824984
err = 1;
49834985
}
4986+
if ((!err) && (len <= 0)) {
4987+
err = 1;
4988+
}
49844989
if (!err) {
49854990
if (sig != NULL) {
49864991
/* Use the ECDSA signature object passed in. */

src/pk_rsa.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,10 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **out,
454454
WOLFSSL_ERROR_MSG("Bad argument");
455455
err = 1;
456456
}
457+
if ((!err) && (derSz <= 0)) {
458+
WOLFSSL_ERROR_MSG("Bad argument");
459+
err = 1;
460+
}
457461
/* Create a new RSA key to return. */
458462
if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) {
459463
WOLFSSL_ERROR_MSG("RSA_new failed");
@@ -503,6 +507,10 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **out,
503507
WOLFSSL_ERROR_MSG("Bad argument");
504508
err = 1;
505509
}
510+
if ((!err) && (derSz <= 0)) {
511+
WOLFSSL_ERROR_MSG("Bad argument");
512+
err = 1;
513+
}
506514
/* Create a new RSA key to return. */
507515
if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) {
508516
WOLFSSL_ERROR_MSG("RSA_new failed");

src/ssl_asn1.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -913,7 +913,7 @@ WOLFSSL_ASN1_BIT_STRING* wolfSSL_d2i_ASN1_BIT_STRING(
913913

914914
WOLFSSL_ENTER("wolfSSL_d2i_ASN1_BIT_STRING");
915915

916-
if (src == NULL || *src == NULL || len == 0)
916+
if (src == NULL || *src == NULL || len <= 0)
917917
return NULL;
918918

919919
if (GetASNTag(*src, &idx, &tag, (word32)len) < 0)
@@ -2984,7 +2984,7 @@ static WOLFSSL_ASN1_STRING* d2i_ASN1_STRING(WOLFSSL_ASN1_STRING** out,
29842984

29852985
WOLFSSL_ENTER("d2i_ASN1_STRING");
29862986

2987-
if (src == NULL || *src == NULL || len == 0)
2987+
if (src == NULL || *src == NULL || len <= 0)
29882988
return NULL;
29892989

29902990
if (GetASNTag(*src, &idx, &tag, (word32)len) < 0)
@@ -3159,16 +3159,21 @@ int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, int sz)
31593159
}
31603160

31613161
if (ret == 1) {
3162+
/* Cast to size_t BEFORE adding 1 to prevent signed overflow
3163+
* when sz == INT_MAX. By this point sz >= 0 (negative sz is
3164+
* handled above as OpenSSL -1/strlen compat). */
3165+
size_t allocSz = (size_t)sz + 1;
3166+
31623167
/* Dispose of any existing dynamic data. */
31633168
if (asn1->isDynamic) {
31643169
XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL);
31653170
asn1->data = NULL;
31663171
}
31673172

31683173
/* Check string will fit - including NUL. */
3169-
if (sz + 1 > CTC_NAME_SIZE) {
3174+
if (allocSz > CTC_NAME_SIZE) {
31703175
/* Allocate new buffer. */
3171-
asn1->data = (char*)XMALLOC((size_t)(sz + 1), NULL,
3176+
asn1->data = (char*)XMALLOC(allocSz, NULL,
31723177
DYNAMIC_TYPE_OPENSSL);
31733178
if (asn1->data == NULL) {
31743179
ret = 0;

src/ssl_load.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,6 +2416,10 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz,
24162416
if ((ret == 0) && (type == CHAIN_CERT_TYPE)) {
24172417
ret = BAD_FUNC_ARG;
24182418
}
2419+
/* Reject negative size - would wrap to huge word32. */
2420+
if ((ret == 0) && (sz < 0)) {
2421+
ret = BAD_FUNC_ARG;
2422+
}
24192423

24202424
#ifdef WOLFSSL_SMALL_STACK
24212425
if (ret == 0) {

src/x509.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4132,7 +4132,7 @@ static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
41324132

41334133
WOLFSSL_ENTER("wolfSSL_X509_d2i");
41344134

4135-
if (in != NULL && len != 0
4135+
if (in != NULL && len > 0
41364136
#ifndef WOLFSSL_CERT_REQ
41374137
&& req == 0
41384138
#else
@@ -11209,7 +11209,7 @@ WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out,
1120911209

1121011210
WOLFSSL_ENTER("wolfSSL_d2i_X509_ALGOR");
1121111211

11212-
if (src == NULL || *src == NULL || len == 0)
11212+
if (src == NULL || *src == NULL || len <= 0)
1121311213
return NULL;
1121411214

1121511215
if (GetAlgoId(*src, &idx, &oid, oidIgnoreType, (word32)len) != 0)

wolfcrypt/src/asn.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24399,10 +24399,10 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
2439924399
const char* headerEnd = NULL;
2440024400
const char* footerEnd = NULL;
2440124401
const char* consumedEnd = NULL;
24402-
const char* bufferEnd = (const char*)(buff + longSz);
24402+
const char* bufferEnd = NULL;
2440324403
long neededSz;
2440424404
int ret = 0;
24405-
word32 sz = (word32)longSz;
24405+
word32 sz = 0;
2440624406
int encrypted_key = 0;
2440724407
DerBuffer* der;
2440824408
word32 algId = 0;
@@ -24423,6 +24423,14 @@ int PemToDer(const unsigned char* buff, long longSz, int type,
2442324423

2442424424
WOLFSSL_ENTER("PemToDer");
2442524425

24426+
/* Reject negative size - would wrap word32 and corrupt pointer arithmetic. */
24427+
if (longSz < 0) {
24428+
return BAD_FUNC_ARG;
24429+
}
24430+
24431+
bufferEnd = (const char*)(buff + longSz);
24432+
sz = (word32)longSz;
24433+
2442624434
/* get PEM header and footer based on type */
2442724435
ret = wc_PemGetHeaderFooter(type, &header, &footer);
2442824436
if (ret != 0)
@@ -29679,6 +29687,9 @@ int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz)
2967929687
if (cert == NULL) {
2968029688
ret = BAD_FUNC_ARG;
2968129689
}
29690+
else if (derSz < 0) {
29691+
ret = BAD_FUNC_ARG;
29692+
}
2968229693
else {
2968329694
/* Check if decodedCert is cached */
2968429695
if (cert->der != der) {
@@ -30183,6 +30194,9 @@ int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz)
3018330194
if (cert == NULL) {
3018430195
ret = BAD_FUNC_ARG;
3018530196
}
30197+
else if (derSz < 0) {
30198+
ret = BAD_FUNC_ARG;
30199+
}
3018630200
else {
3018730201
cert->selfSigned = 0;
3018830202

@@ -30212,6 +30226,9 @@ int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz)
3021230226
if (cert == NULL) {
3021330227
ret = BAD_FUNC_ARG;
3021430228
}
30229+
else if (derSz < 0) {
30230+
ret = BAD_FUNC_ARG;
30231+
}
3021530232
else {
3021630233
/* Check if decodedCert is cached */
3021730234
if (cert->der != der) {
@@ -30239,6 +30256,9 @@ int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz)
3023930256
if (cert == NULL) {
3024030257
ret = BAD_FUNC_ARG;
3024130258
}
30259+
else if (derSz < 0) {
30260+
ret = BAD_FUNC_ARG;
30261+
}
3024230262
else {
3024330263
/* Check if decodedCert is cached */
3024430264
if (cert->der != der) {
@@ -30273,6 +30293,9 @@ int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz)
3027330293
if (cert == NULL) {
3027430294
ret = BAD_FUNC_ARG;
3027530295
}
30296+
else if (derSz < 0) {
30297+
ret = BAD_FUNC_ARG;
30298+
}
3027630299
else {
3027730300
/* Check if decodedCert is cached */
3027830301
if (cert->der != der) {
@@ -30310,6 +30333,9 @@ int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz)
3031030333
if (cert == NULL) {
3031130334
ret = BAD_FUNC_ARG;
3031230335
}
30336+
else if (derSz < 0) {
30337+
ret = BAD_FUNC_ARG;
30338+
}
3031330339
else {
3031430340
/* Check if decodedCert is cached */
3031530341
if (cert->der != der) {
@@ -30337,6 +30363,9 @@ int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz)
3033730363
if (cert == NULL) {
3033830364
ret = BAD_FUNC_ARG;
3033930365
}
30366+
else if (derSz < 0) {
30367+
ret = BAD_FUNC_ARG;
30368+
}
3034030369
else {
3034130370
/* Check if decodedCert is cached */
3034230371
if (cert->der != der) {

wolfcrypt/src/evp_pk.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,12 +1452,18 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey,
14521452
{
14531453
int ret;
14541454
WOLFSSL_EVP_PKEY* key = NULL;
1455-
const byte* der = *pp;
1455+
const byte* der;
14561456
word32 idx = 0;
14571457
int len = 0;
14581458
int cnt = 0;
14591459
word32 algId;
1460-
word32 keyLen = (word32)length;
1460+
word32 keyLen;
1461+
1462+
if (pp == NULL || *pp == NULL || length <= 0)
1463+
return NULL;
1464+
1465+
der = *pp;
1466+
keyLen = (word32)length;
14611467

14621468
/* Take off PKCS#8 wrapper if found. */
14631469
if ((len = ToTraditionalInline_ex(der, &idx, keyLen, &algId)) >= 0) {

0 commit comments

Comments
 (0)