Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit c5d1aeb

Browse files
emargolisrobszewczyk
authored andcommitted
Prevent Integer Overflow In ASN1Writer::EncodeHead(), Certificate, and Key Read Utility Function.
-- Promoted internal length variable (totalLen) from uint16_t to uint32_t. -- Added check that the valid length value (len) is provided as function input. -- Added checks to validate appropriate certificate and key sizes to prevent integer overflow. This change addresses CVE security vulnerability: CVE-2019-5039
1 parent 55e293c commit c5d1aeb

File tree

3 files changed

+13
-1
lines changed

3 files changed

+13
-1
lines changed

src/lib/support/ASN1Writer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,14 +427,17 @@ ASN1_ERROR ASN1Writer::EncodeHead(uint8_t cls, uint32_t tag, bool isConstructed,
427427
{
428428
ASN1_ERROR err = ASN1_NO_ERROR;
429429
uint8_t lenOfLen;
430-
uint16_t totalLen;
430+
uint32_t totalLen;
431431

432432
// Do nothing for a null writer.
433433
VerifyOrExit(mBuf != NULL, err = ASN1_NO_ERROR);
434434

435435
// Only tags <= 31 supported. The implication of this is that encoded tags are exactly 1 byte long.
436436
VerifyOrExit(tag <= 0x1F, err = ASN1_ERROR_UNSUPPORTED_ENCODING);
437437

438+
// Only positive and kUnkownLength values are supported for len input.
439+
VerifyOrExit(len >= 0 || len == kUnkownLength, err = ASN1_ERROR_UNSUPPORTED_ENCODING);
440+
438441
// Compute the number of bytes required to encode the length.
439442
lenOfLen = GetLengthOfLength(len);
440443

src/tools/weave/CertUtils.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ bool ReadCert(const char *fileName, X509 *& cert, CertFormat& origCertFmt)
6363
if (!ReadFileIntoMem(fileName, certBuf, certLen))
6464
ExitNow(res = false);
6565

66+
VerifyOrExit(certLen <= MAX_CERT_SIZE, res = false);
67+
6668
curCertFmt = origCertFmt = DetectCertFormat(certBuf, certLen);
6769

6870
if (curCertFmt == kCertFormat_X509_PEM)
@@ -150,6 +152,8 @@ bool ReadWeaveCert(const char *fileName, uint8_t *& certBuf, uint32_t& certLen)
150152
if (!ReadFileIntoMem(fileName, certBuf, certLen))
151153
ExitNow(res = false);
152154

155+
VerifyOrExit(certLen <= MAX_CERT_SIZE, res = false);
156+
153157
certFmt = DetectCertFormat(certBuf, certLen);
154158
if (certFmt != kCertFormat_Weave_Raw && certFmt != kCertFormat_Weave_Base64)
155159
{

src/tools/weave/KeyUtils.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ bool ReadPrivateKey(const char *fileName, const char *prompt, EVP_PKEY *& key)
5151
if (!res)
5252
ExitNow();
5353

54+
VerifyOrExit(keyDataLen <= MAX_KEY_SIZE, res = false);
55+
5456
res = DecodePrivateKey(keyData, keyDataLen, kKeyFormat_Unknown, fileName, prompt, key);
5557

5658
exit:
@@ -69,6 +71,9 @@ bool ReadPublicKey(const char *fileName, EVP_PKEY *& key)
6971
res = ReadFileIntoMem(fileName, keyData, keyDataLen);
7072
if (!res)
7173
ExitNow();
74+
75+
VerifyOrExit(keyDataLen <= MAX_KEY_SIZE, res = false);
76+
7277
res = DecodePublicKey(keyData, keyDataLen, kKeyFormat_Unknown, fileName, key);
7378

7479
exit:

0 commit comments

Comments
 (0)