Fixes for building CRL with Windows. Refactor load_verify_buffer and LoadCRL to use new wc_ReadDir* functions. Added new directory/file API's: wc_ReadDirFirst(), wc_ReadDirNext(), wc_ReadDirClose(). Moved MAX_PATH and MAX_FILENAME_SZ to wc_port.h. Moved BAD_PATH_ERROR into error-crypt.h. The wc_ReadDir is only supported when NO_WOLFSSL_DIR and NO_FILESYSTEM are not defined. Add map to __FUNCTION__ macro in Windows with debug enabled (to resolve build error with VS and __func__ missing). Fix cast warning on response from EncodeOcspRequestExtensions. Fix for cast to call to BuildCertificateStatus.

This commit is contained in:
David Garske
2017-03-08 11:21:11 -08:00
parent e7445b8e49
commit a55ebb4c18
12 changed files with 245 additions and 157 deletions

98
src/crl.c Normal file → Executable file
View File

@ -34,11 +34,6 @@
#include <wolfssl/internal.h>
#include <wolfssl/error-ssl.h>
#ifndef NO_FILESYSTEM
#include <dirent.h>
#include <sys/stat.h>
#endif
#include <string.h>
#ifdef HAVE_CRL_MONITOR
@ -790,74 +785,62 @@ static int StartMonitorCRL(WOLFSSL_CRL* crl)
#endif /* HAVE_CRL_MONITOR */
#ifndef NO_FILESYSTEM
#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
/* Load CRL path files of type, SSL_SUCCESS on ok */
int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
{
struct dirent* entry;
DIR* dir;
int ret = SSL_SUCCESS;
char* name = NULL;
#ifdef WOLFSSL_SMALL_STACK
char* name;
ReadDirCtx* readCtx = NULL;
#else
char name[MAX_FILENAME_SZ];
ReadDirCtx readCtx[1];
#endif
WOLFSSL_ENTER("LoadCRL");
if (crl == NULL)
return BAD_FUNC_ARG;
dir = opendir(path);
if (dir == NULL) {
WOLFSSL_MSG("opendir path crl load failed");
return BAD_PATH_ERROR;
}
#ifdef WOLFSSL_SMALL_STACK
name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ReadDirCtx* readCtx = NULL;
readCtx = (char*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (name == NULL)
return MEMORY_E;
#endif
while ( (entry = readdir(dir)) != NULL) {
struct stat s;
XMEMSET(name, 0, MAX_FILENAME_SZ);
XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
XSTRNCAT(name, "/", 1);
XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
if (stat(name, &s) != 0) {
WOLFSSL_MSG("stat on name failed");
continue;
}
if (s.st_mode & S_IFREG) {
if (type == SSL_FILETYPE_PEM) {
if (XSTRSTR(entry->d_name, ".pem") == NULL) {
WOLFSSL_MSG("not .pem file, skipping");
continue;
}
}
else {
if (XSTRSTR(entry->d_name, ".der") == NULL &&
XSTRSTR(entry->d_name, ".crl") == NULL) {
WOLFSSL_MSG("not .der or .crl file, skipping");
continue;
}
}
if (ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
!= SSL_SUCCESS) {
WOLFSSL_MSG("CRL file load failed, continuing");
/* try to load each regular file in path */
ret = wc_ReadDirFirst(readCtx, path, &name);
while (ret == 0 && name) {
int skip = 0;
if (type == SSL_FILETYPE_PEM) {
if (XSTRSTR(name, ".pem") == NULL) {
WOLFSSL_MSG("not .pem file, skipping");
skip = 1;
}
}
else {
if (XSTRSTR(name, ".der") == NULL &&
XSTRSTR(name, ".crl") == NULL)
{
WOLFSSL_MSG("not .der or .crl file, skipping");
skip = 1;
}
}
if (!skip && ProcessFile(NULL, name, type, CRL_TYPE, NULL, 0, crl)
!= SSL_SUCCESS) {
WOLFSSL_MSG("CRL file load failed, continuing");
}
ret = wc_ReadDirNext(readCtx, path, &name);
}
wc_ReadDirClose(readCtx);
ret = SSL_SUCCESS; /* load failures not reported, for backwards compat */
#ifdef WOLFSSL_SMALL_STACK
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
if (monitor & WOLFSSL_CRL_MONITOR) {
@ -901,12 +884,21 @@ int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
}
}
closedir(dir);
return ret;
}
#endif /* NO_FILESYSTEM */
#else
int LoadCRL(WOLFSSL_CRL* crl, const char* path, int type, int monitor)
{
(void)crl;
(void)path;
(void)type;
(void)monitor;
/* stub for scenario where file system is not supported */
return NOT_COMPILED_IN;
}
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
#endif /* HAVE_CRL */
#endif /* !WOLFCRYPT_ONLY */

View File

@ -11201,7 +11201,7 @@ int SendCertificateStatus(WOLFSSL* ssl)
if (responses[0].buffer) {
if (ret == 0)
ret = BuildCertificateStatus(ssl, status_type,
responses, i + 1);
responses, (byte)i + 1);
for (i = 0; i < 1 + MAX_CHAIN_DEPTH; i++)
if (responses[i].buffer)
@ -11713,8 +11713,6 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e)
case NOT_CA_ERROR:
return "Not a CA by basic constraint error";
case BAD_PATH_ERROR:
return "Bad path for opendir error";
case BAD_CERT_MANAGER_ERROR:
return "Bad Cert Manager error";

107
src/ssl.c
View File

@ -93,18 +93,6 @@
#include <wolfssl/wolfcrypt/dh.h>
#endif
#ifndef NO_FILESYSTEM
#if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR) \
&& !defined(EBSNET)
#include <dirent.h>
#include <sys/stat.h>
#endif
#ifdef EBSNET
#include "vfapi.h"
#include "vfile.h"
#endif
#endif /* NO_FILESYSTEM */
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_HAVE_MAX)
#define WOLFSSL_HAVE_MAX
@ -5079,7 +5067,6 @@ int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
int ret = SSL_SUCCESS;
WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
(void)path;
if (ctx == NULL || (file == NULL && path == NULL) )
return SSL_FAILURE;
@ -5088,94 +5075,30 @@ int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
ret = ProcessFile(ctx, file, SSL_FILETYPE_PEM, CA_TYPE, NULL, 0, NULL);
if (ret == SSL_SUCCESS && path) {
/* try to load each regular file in path */
#ifdef USE_WINDOWS_API
WIN32_FIND_DATAA FindFileData;
HANDLE hFind;
char* name = NULL;
#ifdef WOLFSSL_SMALL_STACK
char* name = NULL;
#else
char name[MAX_FILENAME_SZ];
#endif
#ifdef WOLFSSL_SMALL_STACK
name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
ReadDirCtx* readCtx = NULL;
readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap,
DYNAMIC_TYPE_TMP_BUFFER);
if (name == NULL)
return MEMORY_E;
#endif
XMEMSET(name, 0, MAX_FILENAME_SZ);
XSTRNCPY(name, path, MAX_FILENAME_SZ - 4);
XSTRNCAT(name, "\\*", 3);
hFind = FindFirstFileA(name, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) {
WOLFSSL_MSG("FindFirstFile for path verify locations failed");
#ifdef WOLFSSL_SMALL_STACK
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return BAD_PATH_ERROR;
}
do {
if (FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 3);
XSTRNCAT(name, "\\", 2);
XSTRNCAT(name, FindFileData.cFileName, MAX_FILENAME_SZ/2);
ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
NULL, 0, NULL);
}
} while (ret == SSL_SUCCESS && FindNextFileA(hFind, &FindFileData));
#ifdef WOLFSSL_SMALL_STACK
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
FindClose(hFind);
#elif !defined(NO_WOLFSSL_DIR)
struct dirent* entry;
DIR* dir = opendir(path);
#ifdef WOLFSSL_SMALL_STACK
char* name = NULL;
#else
char name[MAX_FILENAME_SZ];
ReadDirCtx readCtx[1];
#endif
if (dir == NULL) {
WOLFSSL_MSG("opendir path verify locations failed");
return BAD_PATH_ERROR;
/* try to load each regular file in path */
ret = wc_ReadDirFirst(readCtx, path, &name);
while (ret == 0 && name) {
ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
NULL, 0, NULL);
if (ret != SSL_SUCCESS)
break;
ret = wc_ReadDirNext(readCtx, path, &name);
}
wc_ReadDirClose(readCtx);
#ifdef WOLFSSL_SMALL_STACK
name = (char*)XMALLOC(MAX_FILENAME_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (name == NULL) {
closedir(dir);
return MEMORY_E;
}
#endif
while ( ret == SSL_SUCCESS && (entry = readdir(dir)) != NULL) {
struct stat s;
XMEMSET(name, 0, MAX_FILENAME_SZ);
XSTRNCPY(name, path, MAX_FILENAME_SZ/2 - 2);
XSTRNCAT(name, "/", 1);
XSTRNCAT(name, entry->d_name, MAX_FILENAME_SZ/2);
if (stat(name, &s) != 0) {
WOLFSSL_MSG("stat on name failed");
ret = BAD_PATH_ERROR;
} else if (s.st_mode & S_IFREG)
ret = ProcessFile(ctx, name, SSL_FILETYPE_PEM, CA_TYPE,
NULL, 0, NULL);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(name, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
closedir(dir);
XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_TMP_BUFFER);
#endif
}

4
src/tls.c Normal file → Executable file
View File

@ -2044,7 +2044,7 @@ static word16 TLSX_CSR_Write(CertificateStatusRequest* csr, byte* output,
/* request extensions */
if (csr->request.ocsp.nonceSz)
length = EncodeOcspRequestExtensions(
length = (word16)EncodeOcspRequestExtensions(
&csr->request.ocsp,
output + offset + OPAQUE16_LEN,
OCSP_NONCE_EXT_SZ);
@ -2397,7 +2397,7 @@ static word16 TLSX_CSR2_Write(CertificateStatusRequestItemV2* csr2,
length = 0;
if (csr2->request.ocsp[0].nonceSz)
length = EncodeOcspRequestExtensions(
length = (word16)EncodeOcspRequestExtensions(
&csr2->request.ocsp[0],
output + offset + OPAQUE16_LEN,
OCSP_NONCE_EXT_SZ);

View File

@ -419,6 +419,9 @@ const char* wc_GetErrorString(int error)
case DH_CHECK_PUB_E:
return "DH Check Public Key failure";
case BAD_PATH_ERROR:
return "Bad path for opendir error";
default:
return "unknown error number";

View File

@ -28,6 +28,7 @@
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/wc_port.h>
/* IPP header files for library initialization */
#ifdef HAVE_FAST_RSA
@ -126,6 +127,138 @@ int wolfCrypt_Cleanup(void)
return ret;
}
#if !defined(NO_FILESYSTEM) && !defined(NO_WOLFSSL_DIR)
/* File Handling Helpers */
int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name)
{
int ret = 0;
if (name)
*name = NULL;
if (ctx == NULL || path == NULL) {
return BAD_FUNC_ARG;
}
XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
#ifdef USE_WINDOWS_API
XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ - 4);
XSTRNCAT(ctx->name, "\\*", 3);
ctx->hFind = FindFirstFileA(ctx->name, &ctx->FindFileData);
if (ctx->hFind == INVALID_HANDLE_VALUE) {
WOLFSSL_MSG("FindFirstFile for path verify locations failed");
return BAD_PATH_ERROR;
}
do {
if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3);
XSTRNCAT(ctx->name, "\\", 2);
XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2);
if (name)
*name = ctx->name;
return 0;
}
} while (FindNextFileA(ctx->hFind, &ctx->FindFileData));
#else
ctx->dir = opendir(path);
if (ctx->dir == NULL) {
WOLFSSL_MSG("opendir path verify locations failed");
return BAD_PATH_ERROR;
}
while ((ctx->entry = readdir(ctx->dir)) != NULL) {
XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2);
XSTRNCAT(ctx->name, "/", 1);
XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2);
if (stat(ctx->name, &ctx->s) != 0) {
WOLFSSL_MSG("stat on name failed");
ret = BAD_PATH_ERROR;
break;
} else if (ctx->s.st_mode & S_IFREG) {
if (name)
*name = ctx->name;
return 0;
}
}
#endif
wc_ReadDirClose(ctx);
return ret;
}
int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name)
{
int ret = -1;
if (name)
*name = NULL;
if (ctx == NULL || path == NULL) {
return BAD_FUNC_ARG;
}
XMEMSET(ctx->name, 0, MAX_FILENAME_SZ);
#ifdef USE_WINDOWS_API
while (FindNextFileA(ctx->hFind, &ctx->FindFileData)) {
if (ctx->FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY) {
XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 3);
XSTRNCAT(ctx->name, "\\", 2);
XSTRNCAT(ctx->name, ctx->FindFileData.cFileName, MAX_FILENAME_SZ/2);
if (name)
*name = ctx->name;
return 0;
}
}
#else
while ((ctx->entry = readdir(ctx->dir)) != NULL) {
XSTRNCPY(ctx->name, path, MAX_FILENAME_SZ/2 - 2);
XSTRNCAT(ctx->name, "/", 1);
XSTRNCAT(ctx->name, ctx->entry->d_name, MAX_FILENAME_SZ/2);
if (stat(ctx->name, &ctx->s) != 0) {
WOLFSSL_MSG("stat on name failed");
ret = BAD_PATH_ERROR;
break;
} else if (ctx->s.st_mode & S_IFREG) {
if (name)
*name = ctx->name;
return 0;
}
}
#endif
wc_ReadDirClose(ctx);
return ret;
}
void wc_ReadDirClose(ReadDirCtx* ctx)
{
if (ctx == NULL) {
return;
}
#ifdef USE_WINDOWS_API
if (ctx->hFind != INVALID_HANDLE_VALUE) {
FindClose(ctx->hFind);
ctx->hFind = INVALID_HANDLE_VALUE;
}
#else
if (ctx->dir) {
closedir(ctx->dir);
ctx->dir = NULL;
}
#endif
}
#endif /* !NO_FILESYSTEM && !NO_WOLFSSL_DIR */
wolfSSL_Mutex* wc_InitAndAllocMutex()
{

View File

@ -90,7 +90,7 @@ enum wolfSSL_ErrorCodes {
ECC_EXPORT_ERROR = -354, /* Bad ECC Export Key */
ECC_SHARED_ERROR = -355, /* Bad ECC Shared Secret */
NOT_CA_ERROR = -357, /* Not a CA cert error */
BAD_PATH_ERROR = -358, /* Bad path for opendir */
BAD_CERT_MANAGER_ERROR = -359, /* Bad Cert Manager */
OCSP_CERT_REVOKED = -360, /* OCSP Certificate revoked */
CRL_CERT_REVOKED = -361, /* CRL Certificate revoked */

View File

@ -1064,7 +1064,6 @@ enum Misc {
MAX_X509_SIZE = 2048, /* max static x509 buffer size */
CERT_MIN_SIZE = 256, /* min PEM cert size with header/footer */
MAX_FILENAME_SZ = 256, /* max file name length */
FILE_BUFFER_SIZE = 1024, /* default static file buffer size for input,
will use dynamic buffer if not big enough */

View File

@ -1285,10 +1285,6 @@ static INLINE void CaCb(unsigned char* der, int sz, int type)
/* Wolf Root Directory Helper */
/* KEIL-RL File System does not support relative directory */
#if !defined(WOLFSSL_MDK_ARM) && !defined(WOLFSSL_KEIL_FS) && !defined(WOLFSSL_TIRTOS)
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
/* Maximum depth to search for WolfSSL root */
#define MAX_WOLF_ROOT_DEPTH 5

View File

@ -184,6 +184,7 @@ enum {
WC_CLEANUP_E = -241, /* wolfcrypt cleanup failed */
ECC_CDH_KAT_FIPS_E = -242, /* ECC CDH Known Answer Test failure */
DH_CHECK_PUB_E = -243, /* DH Check Pub Key error */
BAD_PATH_ERROR = -244, /* Bad path for opendir */
MIN_CODE_E = -300 /* errors -101 - -299 */

View File

@ -60,6 +60,10 @@ WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function);
#endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */
#ifdef DEBUG_WOLFSSL
#if defined ( WIN32 )
#define __func__ __FUNCTION__
#endif
/* a is prepended to m and b is appended, creating a log msg a + m + b */
#define WOLFSSL_LOG_CAT(a, m, b) #a " " m " " #b

View File

@ -192,6 +192,9 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
#ifndef NO_FILESYSTEM
#if defined(EBSNET)
#include "vfapi.h"
#include "vfile.h"
#define XFILE int
#define XFOPEN(NAME, MODE) vf_open((const char *)NAME, VO_RDONLY, 0);
#define XFSEEK vf_lseek
@ -202,6 +205,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
#define XFCLOSE vf_close
#define XSEEK_END VSEEK_END
#define XBADFILE -1
#define XFGETS(b,s,f) -2 /* Not ported yet */
#elif defined(LSR_FS)
#include <fs.h>
#define XFILE struct fs_file*
@ -214,6 +218,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
#define XFCLOSE fs_close
#define XSEEK_END 0
#define XBADFILE NULL
#define XFGETS(b,s,f) -2 /* Not ported yet */
#elif defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
#define XFILE MQX_FILE_PTR
#define XFOPEN fopen
@ -225,6 +230,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
#define XFCLOSE fclose
#define XSEEK_END IO_SEEK_END
#define XBADFILE NULL
#define XFGETS fgets
#elif defined(MICRIUM)
#include <fs.h>
#define XFILE FS_FILE*
@ -237,6 +243,7 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
#define XFCLOSE fs_fclose
#define XSEEK_END FS_SEEK_END
#define XBADFILE NULL
#define XFGETS(b,s,f) -2 /* Not ported yet */
#else
/* stdio, default case */
#include <stdio.h>
@ -255,9 +262,41 @@ WOLFSSL_API int wolfCrypt_Cleanup(void);
#define XFCLOSE fclose
#define XSEEK_END SEEK_END
#define XBADFILE NULL
#define XFGETS fgets
#if !defined(USE_WINDOWS_API) && !defined(NO_WOLFSSL_DIR)
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#endif
#endif
#endif /* NO_FILESYSTEM */
#ifndef MAX_FILENAME_SZ
#define MAX_FILENAME_SZ 256 /* max file name length */
#endif
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
#if !defined(NO_WOLFSSL_DIR)
typedef struct ReadDirCtx {
#ifdef USE_WINDOWS_API
WIN32_FIND_DATAA FindFileData;
HANDLE hFind;
#else
struct dirent* entry;
DIR* dir;
struct stat s;
#endif
char name[MAX_FILENAME_SZ];
} ReadDirCtx;
WOLFSSL_API int wc_ReadDirFirst(ReadDirCtx* ctx, const char* path, char** name);
WOLFSSL_API int wc_ReadDirNext(ReadDirCtx* ctx, const char* path, char** name);
WOLFSSL_API void wc_ReadDirClose(ReadDirCtx* ctx);
#endif /* !NO_WOLFSSL_DIR */
#endif /* !NO_FILESYSTEM */
/* Windows API defines its own min() macro. */