diff --git a/src/x509.c b/src/x509.c index a901a9aa51..9b2feea18e 100644 --- a/src/x509.c +++ b/src/x509.c @@ -4406,6 +4406,10 @@ const byte* wolfSSL_X509_get_der(WOLFSSL_X509* x509, int* outSz) if (x509 == NULL || x509->derCert == NULL || outSz == NULL) return NULL; + if (x509->derCert->length > (word32)INT_MAX) { + return NULL; + } + *outSz = (int)x509->derCert->length; return x509->derCert->buffer; } @@ -8676,7 +8680,7 @@ int wolfSSL_i2d_X509(WOLFSSL_X509* x509, unsigned char** out) } der = wolfSSL_X509_get_der(x509, &derSz); - if (der == NULL) { + if (der == NULL || derSz <= 0) { WOLFSSL_LEAVE("wolfSSL_i2d_X509", MEMORY_E); return MEMORY_E; } diff --git a/tests/api/test_ossl_x509_io.c b/tests/api/test_ossl_x509_io.c index 900a9c834b..de4e024b96 100644 --- a/tests/api/test_ossl_x509_io.c +++ b/tests/api/test_ossl_x509_io.c @@ -21,6 +21,8 @@ #include +#include + #ifdef NO_INLINE #include #else @@ -72,6 +74,116 @@ int test_wolfSSL_i2d_X509(void) return EXPECT_RESULT(); } +int test_wolfSSL_X509_get_der_length_guards(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA) + const unsigned char* cert_buf = server_cert_der_2048; + const byte* der = NULL; + X509* cert = NULL; + const byte* origBuf = NULL; + word32 origLen = 0; + int derSz = 0; + + ExpectNotNull(d2i_X509(&cert, &cert_buf, sizeof_server_cert_der_2048)); + ExpectNotNull(cert); + ExpectNotNull(cert->derCert); + ExpectNotNull(cert->derCert->buffer); + + if (EXPECT_SUCCESS()) { + origLen = cert->derCert->length; + origBuf = cert->derCert->buffer; + cert->derCert->length = (word32)INT_MAX; + der = wolfSSL_X509_get_der(cert, &derSz); + cert->derCert->length = origLen; + ExpectPtrEq(der, origBuf); + ExpectIntEQ(derSz, INT_MAX); + + cert->derCert->length = ((word32)INT_MAX) + 1U; + der = wolfSSL_X509_get_der(cert, &derSz); + cert->derCert->length = origLen; + ExpectNull(der); + + cert->derCert->length = 0; + der = wolfSSL_X509_get_der(cert, &derSz); + cert->derCert->length = origLen; + ExpectPtrEq(der, origBuf); + ExpectIntEQ(derSz, 0); + + ExpectPtrEq(wolfSSL_X509_get_der(cert, &derSz), origBuf); + ExpectIntGT(derSz, 0); + } + + X509_free(cert); +#endif + return EXPECT_RESULT(); +} + +int test_wolfSSL_i2d_X509_der_length_guards(void) +{ + EXPECT_DECLS; +#if defined(OPENSSL_EXTRA) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA) + const unsigned char* cert_buf = server_cert_der_2048; + unsigned char* overflowOut = NULL; + unsigned char overflowBuf[4] = { 0x11, 0x22, 0x33, 0x44 }; + const unsigned char overflowExpected[4] = { 0x11, 0x22, 0x33, 0x44 }; + unsigned char* overflowCallerOut = overflowBuf; + unsigned char* zeroLenOut = NULL; + unsigned char zeroLenBuf[4] = { 0x55, 0x66, 0x77, 0x88 }; + const unsigned char zeroLenExpected[4] = { 0x55, 0x66, 0x77, 0x88 }; + unsigned char* zeroLenCallerOut = zeroLenBuf; + unsigned char* successOut = NULL; + X509* cert = NULL; + word32 origLen = 0; + int ret = 0; + + ExpectNotNull(d2i_X509(&cert, &cert_buf, sizeof_server_cert_der_2048)); + ExpectNotNull(cert); + ExpectNotNull(cert->derCert); + ExpectNotNull(cert->derCert->buffer); + + if (EXPECT_SUCCESS()) { + origLen = cert->derCert->length; + cert->derCert->length = ((word32)INT_MAX) + 1U; + ret = i2d_X509(cert, &overflowOut); + cert->derCert->length = origLen; + ExpectIntEQ(ret, MEMORY_E); + ExpectNull(overflowOut); + + cert->derCert->length = ((word32)INT_MAX) + 1U; + ret = i2d_X509(cert, &overflowCallerOut); + cert->derCert->length = origLen; + ExpectIntEQ(ret, MEMORY_E); + ExpectPtrEq(overflowCallerOut, overflowBuf); + ExpectIntEQ(XMEMCMP(overflowBuf, overflowExpected, + sizeof(overflowBuf)), 0); + + cert->derCert->length = 0; + ret = i2d_X509(cert, &zeroLenOut); + cert->derCert->length = origLen; + ExpectIntEQ(ret, MEMORY_E); + ExpectNull(zeroLenOut); + + cert->derCert->length = 0; + ret = i2d_X509(cert, &zeroLenCallerOut); + cert->derCert->length = origLen; + ExpectIntEQ(ret, MEMORY_E); + ExpectPtrEq(zeroLenCallerOut, zeroLenBuf); + ExpectIntEQ(XMEMCMP(zeroLenBuf, zeroLenExpected, + sizeof(zeroLenBuf)), 0); + + ExpectIntGT(i2d_X509(cert, &successOut), 0); + ExpectNotNull(successOut); + } + + XFREE(overflowOut, NULL, DYNAMIC_TYPE_OPENSSL); + XFREE(zeroLenOut, NULL, DYNAMIC_TYPE_OPENSSL); + XFREE(successOut, NULL, DYNAMIC_TYPE_OPENSSL); + X509_free(cert); +#endif + return EXPECT_RESULT(); +} + int test_wolfSSL_PEM_read_X509(void) { EXPECT_DECLS; @@ -244,4 +356,3 @@ int test_wolfSSL_PEM_write_bio_X509(void) #endif return EXPECT_RESULT(); } - diff --git a/tests/api/test_ossl_x509_io.h b/tests/api/test_ossl_x509_io.h index ec346fbdd9..f8ef4d4a51 100644 --- a/tests/api/test_ossl_x509_io.h +++ b/tests/api/test_ossl_x509_io.h @@ -25,11 +25,17 @@ #include int test_wolfSSL_i2d_X509(void); +int test_wolfSSL_X509_get_der_length_guards(void); +int test_wolfSSL_i2d_X509_der_length_guards(void); int test_wolfSSL_PEM_read_X509(void); int test_wolfSSL_PEM_write_bio_X509(void); #define TEST_OSSL_X509_IO_DECLS \ TEST_DECL_GROUP("ossl_x509_io", test_wolfSSL_i2d_X509), \ + TEST_DECL_GROUP("ossl_x509_io", \ + test_wolfSSL_X509_get_der_length_guards), \ + TEST_DECL_GROUP("ossl_x509_io", \ + test_wolfSSL_i2d_X509_der_length_guards), \ TEST_DECL_GROUP("ossl_x509_io", test_wolfSSL_PEM_read_X509), \ TEST_DECL_GROUP("ossl_x509_io", test_wolfSSL_PEM_write_bio_X509)