1diff --git a/library/entropy_poll.c b/library/entropy_poll.c 2index 4556f88a5..ba56b70f7 100644 3--- a/library/entropy_poll.c 4+++ b/library/entropy_poll.c 5@@ -61,28 +61,43 @@ 6 #define _WIN32_WINNT 0x0400 7 #endif 8 #include <windows.h> 9-#include <wincrypt.h> 10+#include <bcrypt.h> 11+#if defined(_MSC_VER) && _MSC_VER <= 1600 12+/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and 13+ * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. 14+ * These constants are guaranteed to be the same, though, so we suppress the 15+ * warning when including intsafe.h. 16+ */ 17+#pragma warning( push ) 18+#pragma warning( disable : 4005 ) 19+#endif 20+#include <intsafe.h> 21+#if defined(_MSC_VER) && _MSC_VER <= 1600 22+#pragma warning( pop ) 23+#endif 24 25 int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, 26 size_t *olen ) 27 { 28- HCRYPTPROV provider; 29+ ULONG len_as_ulong = 0; 30 ((void) data); 31 *olen = 0; 32 33- if( CryptAcquireContext( &provider, NULL, NULL, 34- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) 35+ /* 36+ * BCryptGenRandom takes ULONG for size, which is smaller than size_t on 37+ * 64-bit Windows platforms. Ensure len's value can be safely converted into 38+ * a ULONG. 39+ */ 40+ if ( FAILED( SizeTToULong( len, &len_as_ulong ) ) ) 41 { 42 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 43 } 44 45- if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) 46+ if ( !BCRYPT_SUCCESS( BCryptGenRandom( NULL, output, len_as_ulong, BCRYPT_USE_SYSTEM_PREFERRED_RNG ) ) ) 47 { 48- CryptReleaseContext( provider, 0 ); 49 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); 50 } 51 52- CryptReleaseContext( provider, 0 ); 53 *olen = len; 54 55 return( 0 ); 56diff --git a/library/x509_crt.c b/library/x509_crt.c 57index 76558342e..35a134950 100644 58--- a/library/x509_crt.c 59+++ b/library/x509_crt.c 60@@ -65,6 +65,19 @@ 61 62 #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) 63 #include <windows.h> 64+#if defined(_MSC_VER) && _MSC_VER <= 1600 65+/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and 66+ * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. 67+ * These constants are guaranteed to be the same, though, so we suppress the 68+ * warning when including intsafe.h. 69+ */ 70+#pragma warning( push ) 71+#pragma warning( disable : 4005 ) 72+#endif 73+#include <intsafe.h> 74+#if defined(_MSC_VER) && _MSC_VER <= 1600 75+#pragma warning( pop ) 76+#endif 77 #else 78 #include <time.h> 79 #endif 80@@ -1278,6 +1291,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) 81 char filename[MAX_PATH]; 82 char *p; 83 size_t len = strlen( path ); 84+ int lengthAsInt = 0; 85 86 WIN32_FIND_DATAW file_data; 87 HANDLE hFind; 88@@ -1292,7 +1306,18 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) 89 p = filename + len; 90 filename[len++] = '*'; 91 92- w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, 93+ if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) ) 94+ return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); 95+ 96+ /* 97+ * Note this function uses the code page CP_ACP, and assumes the incoming 98+ * string is encoded in ANSI, before translating it into Unicode. If the 99+ * incoming string were changed to be UTF-8, then the length check needs to 100+ * change to check the number of characters, not the number of bytes, in the 101+ * incoming string are less than MAX_PATH to avoid a buffer overrun with 102+ * MultiByteToWideChar(). 103+ */ 104+ w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir, 105 MAX_PATH - 3 ); 106 if( w_ret == 0 ) 107 return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); 108@@ -1309,8 +1334,11 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) 109 if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) 110 continue; 111 112+ if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &lengthAsInt ) ) ) 113+ return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); 114+ 115 w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, 116- lstrlenW( file_data.cFileName ), 117+ lengthAsInt, 118 p, (int) len - 1, 119 NULL, NULL ); 120 if( w_ret == 0 ) 121