diff --git a/src/crl.c b/src/crl.c index 62c207de526..a11fff6f556 100644 --- a/src/crl.c +++ b/src/crl.c @@ -834,7 +834,7 @@ int BufferLoadCRL(WOLFSSL_CRL* crl, const byte* buff, long sz, int type, WOLFSSL_ENTER("BufferLoadCRL"); - if (crl == NULL || buff == NULL || sz == 0) + if (crl == NULL || buff == NULL || sz <= 0) return BAD_FUNC_ARG; if (type == WOLFSSL_FILETYPE_PEM) { @@ -1160,7 +1160,7 @@ int GetCRLInfo(WOLFSSL_CRL* crl, CrlInfo* info, const byte* buff, WOLFSSL_ENTER("GetCRLInfo"); - if (crl == NULL || info == NULL || buff == NULL || sz == 0) + if (crl == NULL || info == NULL || buff == NULL || sz <= 0) return BAD_FUNC_ARG; if (type == WOLFSSL_FILETYPE_PEM) { diff --git a/src/ocsp.c b/src/ocsp.c index 2fff7ced503..5fd4ca6b0da 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -1239,6 +1239,8 @@ OcspResponse* wolfSSL_d2i_OCSP_RESPONSE(OcspResponse** response, if (data == NULL) return NULL; + if (len <= 0) + return NULL; if (response != NULL) resp = *response; diff --git a/src/pk_ec.c b/src/pk_ec.c index 66647c9eb77..1ad33fc8f30 100644 --- a/src/pk_ec.c +++ b/src/pk_ec.c @@ -450,6 +450,8 @@ static WOLFSSL_EC_GROUP* wolfssl_ec_group_d2i(WOLFSSL_EC_GROUP** group, if (in_pp == NULL || *in_pp == NULL) return NULL; + if (inSz <= 0) + return NULL; in = *in_pp; @@ -4977,6 +4979,9 @@ WOLFSSL_ECDSA_SIG* wolfSSL_d2i_ECDSA_SIG(WOLFSSL_ECDSA_SIG** sig, if (pp == NULL) { err = 1; } + if ((!err) && (len <= 0)) { + err = 1; + } if (!err) { if (sig != NULL) { /* Use the ECDSA signature object passed in. */ diff --git a/src/pk_rsa.c b/src/pk_rsa.c index c102f4ec21f..ee816784e43 100644 --- a/src/pk_rsa.c +++ b/src/pk_rsa.c @@ -454,6 +454,10 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPublicKey(WOLFSSL_RSA **out, WOLFSSL_ERROR_MSG("Bad argument"); err = 1; } + if ((!err) && (derSz <= 0)) { + WOLFSSL_ERROR_MSG("Bad argument"); + err = 1; + } /* Create a new RSA key to return. */ if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) { WOLFSSL_ERROR_MSG("RSA_new failed"); @@ -503,6 +507,10 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **out, WOLFSSL_ERROR_MSG("Bad argument"); err = 1; } + if ((!err) && (derSz <= 0)) { + WOLFSSL_ERROR_MSG("Bad argument"); + err = 1; + } /* Create a new RSA key to return. */ if ((!err) && ((rsa = wolfSSL_RSA_new()) == NULL)) { WOLFSSL_ERROR_MSG("RSA_new failed"); diff --git a/src/ssl_asn1.c b/src/ssl_asn1.c index 58aed807d0e..fb1951dd832 100644 --- a/src/ssl_asn1.c +++ b/src/ssl_asn1.c @@ -913,7 +913,7 @@ WOLFSSL_ASN1_BIT_STRING* wolfSSL_d2i_ASN1_BIT_STRING( WOLFSSL_ENTER("wolfSSL_d2i_ASN1_BIT_STRING"); - if (src == NULL || *src == NULL || len == 0) + if (src == NULL || *src == NULL || len <= 0) return NULL; if (GetASNTag(*src, &idx, &tag, (word32)len) < 0) @@ -2984,7 +2984,7 @@ static WOLFSSL_ASN1_STRING* d2i_ASN1_STRING(WOLFSSL_ASN1_STRING** out, WOLFSSL_ENTER("d2i_ASN1_STRING"); - if (src == NULL || *src == NULL || len == 0) + if (src == NULL || *src == NULL || len <= 0) return NULL; if (GetASNTag(*src, &idx, &tag, (word32)len) < 0) @@ -3159,6 +3159,11 @@ int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, int sz) } if (ret == 1) { + /* Cast to size_t BEFORE adding 1 to prevent signed overflow + * when sz == INT_MAX. By this point sz >= 0 (negative sz is + * handled above as OpenSSL -1/strlen compat). */ + size_t allocSz = (size_t)sz + 1; + /* Dispose of any existing dynamic data. */ if (asn1->isDynamic) { XFREE(asn1->data, NULL, DYNAMIC_TYPE_OPENSSL); @@ -3166,9 +3171,9 @@ int wolfSSL_ASN1_STRING_set(WOLFSSL_ASN1_STRING* asn1, const void* data, int sz) } /* Check string will fit - including NUL. */ - if (sz + 1 > CTC_NAME_SIZE) { + if (allocSz > CTC_NAME_SIZE) { /* Allocate new buffer. */ - asn1->data = (char*)XMALLOC((size_t)(sz + 1), NULL, + asn1->data = (char*)XMALLOC(allocSz, NULL, DYNAMIC_TYPE_OPENSSL); if (asn1->data == NULL) { ret = 0; diff --git a/src/ssl_load.c b/src/ssl_load.c index 0a0fb9e467c..cfaa926d551 100644 --- a/src/ssl_load.c +++ b/src/ssl_load.c @@ -2386,6 +2386,10 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, long sz, if ((ret == 0) && (type == CHAIN_CERT_TYPE)) { ret = BAD_FUNC_ARG; } + /* Reject negative size - would wrap to huge word32. */ + if ((ret == 0) && (sz < 0)) { + ret = BAD_FUNC_ARG; + } #ifdef WOLFSSL_SMALL_STACK if (ret == 0) { diff --git a/src/x509.c b/src/x509.c index 46dfd38ed43..1073878093c 100644 --- a/src/x509.c +++ b/src/x509.c @@ -4130,7 +4130,7 @@ static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509, WOLFSSL_ENTER("wolfSSL_X509_d2i"); - if (in != NULL && len != 0 + if (in != NULL && len > 0 #ifndef WOLFSSL_CERT_REQ && req == 0 #else @@ -11202,7 +11202,7 @@ WOLFSSL_X509_ALGOR* wolfSSL_d2i_X509_ALGOR(WOLFSSL_X509_ALGOR** out, WOLFSSL_ENTER("wolfSSL_d2i_X509_ALGOR"); - if (src == NULL || *src == NULL || len == 0) + if (src == NULL || *src == NULL || len <= 0) return NULL; if (GetAlgoId(*src, &idx, &oid, oidIgnoreType, (word32)len) != 0) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index dc0c9ecfecb..31f9756e40a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -23815,10 +23815,10 @@ int PemToDer(const unsigned char* buff, long longSz, int type, const char* headerEnd = NULL; const char* footerEnd = NULL; const char* consumedEnd = NULL; - const char* bufferEnd = (const char*)(buff + longSz); + const char* bufferEnd = NULL; long neededSz; int ret = 0; - word32 sz = (word32)longSz; + word32 sz = 0; int encrypted_key = 0; DerBuffer* der; word32 algId = 0; @@ -23839,6 +23839,14 @@ int PemToDer(const unsigned char* buff, long longSz, int type, WOLFSSL_ENTER("PemToDer"); + /* Reject negative size - would wrap word32 and corrupt pointer arithmetic. */ + if (longSz < 0) { + return BAD_FUNC_ARG; + } + + bufferEnd = (const char*)(buff + longSz); + sz = (word32)longSz; + /* get PEM header and footer based on type */ ret = wc_PemGetHeaderFooter(type, &header, &footer); if (ret != 0) @@ -24322,7 +24330,7 @@ int wc_KeyPemToDer(const unsigned char* pem, int pemSz, WOLFSSL_ENTER("wc_KeyPemToDer"); - if (pem == NULL || (buff != NULL && buffSz <= 0)) { + if (pem == NULL || pemSz < 0 || (buff != NULL && buffSz <= 0)) { WOLFSSL_MSG("Bad pem der args"); return BAD_FUNC_ARG; } @@ -24373,7 +24381,7 @@ int wc_CertPemToDer(const unsigned char* pem, int pemSz, WOLFSSL_ENTER("wc_CertPemToDer"); - if (pem == NULL || buff == NULL || buffSz <= 0) { + if (pem == NULL || pemSz < 0 || buff == NULL || buffSz <= 0) { WOLFSSL_MSG("Bad pem der args"); return BAD_FUNC_ARG; } @@ -24420,7 +24428,7 @@ int wc_PubKeyPemToDer(const unsigned char* pem, int pemSz, WOLFSSL_ENTER("wc_PubKeyPemToDer"); - if (pem == NULL || (buff != NULL && buffSz <= 0)) { + if (pem == NULL || pemSz < 0 || (buff != NULL && buffSz <= 0)) { WOLFSSL_MSG("Bad pem der args"); return BAD_FUNC_ARG; } @@ -29113,6 +29121,9 @@ int wc_SetAuthKeyIdFromCert(Cert *cert, const byte *der, int derSz) if (cert == NULL) { ret = BAD_FUNC_ARG; } + else if (derSz < 0) { + ret = BAD_FUNC_ARG; + } else { /* Check if decodedCert is cached */ if (cert->der != der) { @@ -29583,6 +29594,9 @@ int wc_SetIssuerBuffer(Cert* cert, const byte* der, int derSz) if (cert == NULL) { ret = BAD_FUNC_ARG; } + else if (derSz < 0) { + ret = BAD_FUNC_ARG; + } else { cert->selfSigned = 0; @@ -29612,6 +29626,9 @@ int wc_SetSubjectBuffer(Cert* cert, const byte* der, int derSz) if (cert == NULL) { ret = BAD_FUNC_ARG; } + else if (derSz < 0) { + ret = BAD_FUNC_ARG; + } else { /* Check if decodedCert is cached */ if (cert->der != der) { @@ -29639,6 +29656,9 @@ int wc_SetSubjectRaw(Cert* cert, const byte* der, int derSz) if (cert == NULL) { ret = BAD_FUNC_ARG; } + else if (derSz < 0) { + ret = BAD_FUNC_ARG; + } else { /* Check if decodedCert is cached */ if (cert->der != der) { @@ -29673,6 +29693,9 @@ int wc_SetIssuerRaw(Cert* cert, const byte* der, int derSz) if (cert == NULL) { ret = BAD_FUNC_ARG; } + else if (derSz < 0) { + ret = BAD_FUNC_ARG; + } else { /* Check if decodedCert is cached */ if (cert->der != der) { @@ -29710,6 +29733,9 @@ int wc_SetAltNamesBuffer(Cert* cert, const byte* der, int derSz) if (cert == NULL) { ret = BAD_FUNC_ARG; } + else if (derSz < 0) { + ret = BAD_FUNC_ARG; + } else { /* Check if decodedCert is cached */ if (cert->der != der) { @@ -29737,6 +29763,9 @@ int wc_SetDatesBuffer(Cert* cert, const byte* der, int derSz) if (cert == NULL) { ret = BAD_FUNC_ARG; } + else if (derSz < 0) { + ret = BAD_FUNC_ARG; + } else { /* Check if decodedCert is cached */ if (cert->der != der) { diff --git a/wolfcrypt/src/evp_pk.c b/wolfcrypt/src/evp_pk.c index 7767cb92f49..1316cd17564 100644 --- a/wolfcrypt/src/evp_pk.c +++ b/wolfcrypt/src/evp_pk.c @@ -1099,12 +1099,18 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_AutoPrivateKey(WOLFSSL_EVP_PKEY** pkey, { int ret; WOLFSSL_EVP_PKEY* key = NULL; - const byte* der = *pp; + const byte* der; word32 idx = 0; int len = 0; int cnt = 0; word32 algId; - word32 keyLen = (word32)length; + word32 keyLen; + + if (pp == NULL || *pp == NULL || length <= 0) + return NULL; + + der = *pp; + keyLen = (word32)length; /* Take off PKCS#8 wrapper if found. */ if ((len = ToTraditionalInline_ex(der, &idx, keyLen, &algId)) >= 0) {