* Fixed wolfSSL_CTX_load_verify_locations to continue loading if there is an error (ZD 4265).

* Added new `wolfSSL_CTX_load_verify_locations_ex` that supports flags `WOLFSSL_LOAD_FLAG_IGNORE_ERR`, `WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY` and `WOLFSSL_LOAD_FLAG_PEM_CA_ONLY`.
* Fix for `PemToDer` to handle PEM which may include a null terminator in length at end of file length causing wrong error code to be returned. Added test case for this. (ZD 4278)
* Added macro to override default flags for `wolfSSL_CTX_load_verify_locations` using `WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS`.
* Added tests for loading CA PEM's from directory using `wolfSSL_CTX_load_verify_locations` and `wolfSSL_CTX_load_verify_locations_ex` with flags.
* Added tests for `wolfSSL_CertManagerLoadCABuffer`.
* Updated the expired test certs and added them to `./certs/test/gen-testcerts.sh` script.
This commit is contained in:
David Garske
2018-08-31 15:35:25 -07:00
parent d998d10f02
commit ae3d8d3779
14 changed files with 490 additions and 142 deletions

View File

@@ -5085,7 +5085,7 @@ static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
WOLFSSL_MSG("Trying a CRL");
if (PemToDer(buff + used, sz - used, CRL_TYPE, &der, NULL, &info,
NULL) == 0) {
WOLFSSL_MSG(" Proccessed a CRL");
WOLFSSL_MSG(" Processed a CRL");
wolfSSL_CertManagerLoadCRLBuffer(ctx->cm, der->buffer,
der->length, WOLFSSL_FILETYPE_ASN1);
FreeDer(&der);
@@ -5095,26 +5095,26 @@ static int ProcessChainBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
#endif
#endif
if (ret < 0)
{
if(consumed > 0) { /* Made progress in file */
if (ret < 0) {
if (consumed > 0) { /* Made progress in file */
WOLFSSL_ERROR(ret);
WOLFSSL_MSG("CA Parse failed, with progress in file.");
WOLFSSL_MSG("Search for other certs in file");
} else {
}
else {
WOLFSSL_MSG("CA Parse failed, no progress in file.");
WOLFSSL_MSG("Do not continue search for other certs in file");
break;
}
} else {
}
else {
WOLFSSL_MSG(" Processed a CA");
gotOne = 1;
}
used += consumed;
}
if(gotOne)
{
if (gotOne) {
WOLFSSL_MSG("Processed at least one valid CA. Other stuff OK");
return WOLFSSL_SUCCESS;
}
@@ -5733,17 +5733,18 @@ int ProcessFile(WOLFSSL_CTX* ctx, const char* fname, int format, int type,
return ret;
}
/* loads file then loads each file in path, no c_rehash */
int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
const char* path)
int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file,
const char* path, word32 flags)
{
int ret = WOLFSSL_SUCCESS;
#ifndef NO_WOLFSSL_DIR
int fileRet;
int successCount = 0;
int failCount = 0;
#endif
WOLFSSL_ENTER("wolfSSL_CTX_load_verify_locations");
WOLFSSL_MSG("wolfSSL_CTX_load_verify_locations_ex");
if (ctx == NULL || (file == NULL && path == NULL) )
return WOLFSSL_FAILURE;
@@ -5767,30 +5768,70 @@ int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
/* try to load each regular file in path */
fileRet = wc_ReadDirFirst(readCtx, path, &name);
while (fileRet == 0 && name) {
WOLFSSL_MSG(name); /* log file name */
ret = ProcessFile(ctx, name, WOLFSSL_FILETYPE_PEM, CA_TYPE,
NULL, 0, NULL);
if (ret != WOLFSSL_SUCCESS)
break;
if (ret != WOLFSSL_SUCCESS) {
/* handle flags for ignoring errors, skipping expired certs or
by PEM certificate header error */
if ( (flags & WOLFSSL_LOAD_FLAG_IGNORE_ERR) ||
((flags & WOLFSSL_LOAD_FLAG_DATE_ERR_OKAY) &&
(ret == ASN_BEFORE_DATE_E || ret == ASN_AFTER_DATE_E)) ||
((flags & WOLFSSL_LOAD_FLAG_PEM_CA_ONLY) &&
(ret == ASN_NO_PEM_HEADER))) {
/* Do not fail here if a certificate fails to load,
continue to next file */
ret = WOLFSSL_SUCCESS;
}
else {
WOLFSSL_ERROR(ret);
WOLFSSL_MSG("Load CA file failed, continuing");
failCount++;
}
}
else {
successCount++;
}
fileRet = wc_ReadDirNext(readCtx, path, &name);
}
wc_ReadDirClose(readCtx);
/* pass directory read failure to response code */
if (ret == WOLFSSL_SUCCESS && fileRet != -1) {
if (fileRet != WC_READDIR_NOFILE) {
ret = fileRet;
}
else if (file == NULL && (successCount == 0 || failCount > 0)) {
/* report failure if no files were loaded or there were failures */
/* pass on existing error code if exists */
if (ret == WOLFSSL_SUCCESS)
ret = WOLFSSL_FAILURE;
}
else {
ret = WOLFSSL_SUCCESS;
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(readCtx, ctx->heap, DYNAMIC_TYPE_DIRCTX);
#endif
#else
ret = NOT_COMPILED_IN;
(void)flags;
#endif
}
return ret;
}
#ifndef WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS
#define WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS WOLFSSL_LOAD_FLAG_NONE
#endif
int wolfSSL_CTX_load_verify_locations(WOLFSSL_CTX* ctx, const char* file,
const char* path)
{
return wolfSSL_CTX_load_verify_locations_ex(ctx, file, path,
WOLFSSL_LOAD_VERIFY_DEFAULT_FLAGS);
}
#ifdef WOLFSSL_TRUST_PEER_CERT
/* Used to specify a peer cert to match when connecting