diff --git a/lib/datum.h b/lib/datum.h index 35b9e3b97c8607ffddad73d68b08df9d7eb41a7b..28725d70a86396791e009d18e5e2b72db6392461 100644 --- a/lib/datum.h +++ b/lib/datum.h @@ -44,6 +44,7 @@ void _gnutls_free_datum(gnutls_datum_t * dat) { if (dat != NULL) { gnutls_free(dat->data); + dat->data = NULL; dat->size = 0; } } diff --git a/lib/fips.c b/lib/fips.c index 51567953df9437324d52ea80bbb3070fecdfb94f..bbf3181ba264659698d2b83ab688f5d4ec46e51f 100644 --- a/lib/fips.c +++ b/lib/fips.c @@ -145,135 +145,172 @@ void _gnutls_fips_mode_reset_zombie(void) #define HMAC_SIZE 32 #define HMAC_ALGO GNUTLS_MAC_SHA256 -static int get_library_path(const char* lib, const char* symbol, char* path, size_t path_size) +static char * +get_library_path(const char* lib, const char* symbol) { -Dl_info info; -int ret; -void *dl, *sym; + Dl_info info; + int ret; + void *dl, *sym; + char *path = NULL; dl = dlopen(lib, RTLD_LAZY); - if (dl == NULL) - return gnutls_assert_val(GNUTLS_E_FILE_ERROR); + if (dl == NULL) { + return NULL; + } sym = dlsym(dl, symbol); if (sym == NULL) { - ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR); goto cleanup; } ret = dladdr(sym, &info); if (ret == 0) { - ret = gnutls_assert_val(GNUTLS_E_FILE_ERROR); goto cleanup; } - snprintf(path, path_size, "%s", info.dli_fname); + path = strdup(info.dli_fname); - ret = 0; cleanup: dlclose(dl); - return ret; + return path; } -static void get_hmac_file(char *mac_file, size_t mac_file_size, const char* orig) +static char * +get_hmac_file(const char *orig) { -char* p; + char *p; + char *path = NULL; p = strrchr(orig, '/'); - if (p==NULL) { - snprintf(mac_file, mac_file_size, ".%s"HMAC_SUFFIX, orig); - return; + if (p) { + if (asprintf(&path, "%.*s/.%s"HMAC_SUFFIX, + (int)(p - orig), orig, p + 1) < 0) { + return NULL; + } + } else { + if (asprintf(&path, ".%s"HMAC_SUFFIX, orig) < 0) { + return NULL; + } } - snprintf(mac_file, mac_file_size, "%.*s/.%s"HMAC_SUFFIX, (int)(p-orig), orig, p+1); + return path; } -static void get_hmac_file2(char *mac_file, size_t mac_file_size, const char* orig) +static char * +get_hmac_file2(const char *orig) { -char* p; + char *p; + char *path = NULL; p = strrchr(orig, '/'); - if (p==NULL) { - snprintf(mac_file, mac_file_size, "fipscheck/%s"HMAC_SUFFIX, orig); - return; + if (p) { + if (asprintf(&path, "%.*s/fipscheck/%s"HMAC_SUFFIX, + (int)(p - orig), orig, p + 1) < 0) { + return NULL; + } + } else { + if (asprintf(&path, "fipscheck/%s"HMAC_SUFFIX, orig) < 0) { + return NULL; + } } - snprintf(mac_file, mac_file_size, "%.*s/fipscheck/%s"HMAC_SUFFIX, (int)(p-orig), orig, p+1); + return path; } /* Run an HMAC using the key above on the library binary data. * Returns true on success and false on error. */ -static unsigned check_binary_integrity(const char* libname, const char* symbol) +static bool check_binary_integrity(const char *libname, const char *symbol) { int ret; unsigned prev; - char mac_file[GNUTLS_PATH_MAX]; - char file[GNUTLS_PATH_MAX]; + char *mac_file = NULL; + char *file = NULL; uint8_t hmac[HMAC_SIZE]; uint8_t new_hmac[HMAC_SIZE]; size_t hmac_size; - gnutls_datum_t data; - - ret = get_library_path(libname, symbol, file, sizeof(file)); - if (ret < 0) { - _gnutls_debug_log("Could not get path for library %s\n", libname); - return 0; + gnutls_datum_t data = { NULL, 0 }; + bool ok = true; + + file = get_library_path(libname, symbol); + if (!file) { + _gnutls_debug_log("Could not get path for library %s\n", + libname); + ok = false; + goto cleanup; } _gnutls_debug_log("Loading: %s\n", file); ret = gnutls_load_file(file, &data); if (ret < 0) { _gnutls_debug_log("Could not load: %s\n", file); - return gnutls_assert_val(0); + ok = gnutls_assert_val(false); + goto cleanup; } prev = _gnutls_get_lib_state(); _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); ret = gnutls_hmac_fast(HMAC_ALGO, FIPS_KEY, sizeof(FIPS_KEY)-1, - data.data, data.size, new_hmac); + data.data, data.size, new_hmac); + _gnutls_free_datum(&data); _gnutls_switch_lib_state(prev); - - gnutls_free(data.data); - - if (ret < 0) - return gnutls_assert_val(0); + if (ret < 0) { + ok = gnutls_assert_val(false); + goto cleanup; + } /* now open the .hmac file and compare */ - get_hmac_file(mac_file, sizeof(mac_file), file); + mac_file = get_hmac_file(file); + if (!mac_file) { + ok = gnutls_assert_val(false); + goto cleanup; + } ret = gnutls_load_file(mac_file, &data); if (ret < 0) { - get_hmac_file2(mac_file, sizeof(mac_file), file); + free(mac_file); + mac_file = get_hmac_file2(file); + if (!mac_file) { + ok = gnutls_assert_val(false); + goto cleanup; + } + ret = gnutls_load_file(mac_file, &data); if (ret < 0) { - _gnutls_debug_log("Could not open %s for MAC testing: %s\n", mac_file, gnutls_strerror(ret)); - return gnutls_assert_val(0); + _gnutls_debug_log("Could not open %s for MAC testing: %s\n", + mac_file, gnutls_strerror(ret)); + ok = gnutls_assert_val(false); + goto cleanup; } } hmac_size = hex_data_size(data.size); /* trim eventual newlines from the end of the data read from file */ - while ((data.size > 0) && (data.data[data.size - 1] == '\n')) { + while (data.size > 0 && data.data[data.size - 1] == '\n') { data.data[data.size - 1] = 0; data.size--; } ret = gnutls_hex_decode(&data, hmac, &hmac_size); - gnutls_free(data.data); - + _gnutls_free_datum(&data); if (ret < 0) { _gnutls_debug_log("Could not convert hex data to binary for MAC testing for %s.\n", libname); - return gnutls_assert_val(0); + ok = gnutls_assert_val(false); + goto cleanup; } if (hmac_size != sizeof(hmac) || - memcmp(hmac, new_hmac, sizeof(hmac)) != 0) { + memcmp(hmac, new_hmac, sizeof(hmac)) != 0) { _gnutls_debug_log("Calculated MAC for %s does not match\n", libname); - return gnutls_assert_val(0); + ok = gnutls_assert_val(false); + goto cleanup; } _gnutls_debug_log("Successfully verified MAC for %s (%s)\n", mac_file, libname); - - return 1; + + cleanup: + free(file); + free(mac_file); + _gnutls_free_datum(&data); + return ok; } int _gnutls_fips_perform_self_checks1(void) @@ -463,26 +500,25 @@ int _gnutls_fips_perform_self_checks2(void) } if (_skip_integrity_checks == 0) { - ret = check_binary_integrity(GNUTLS_LIBRARY_NAME, "gnutls_global_init"); - if (ret == 0) { + if (!check_binary_integrity(GNUTLS_LIBRARY_NAME, + "gnutls_global_init")) { gnutls_assert(); goto error; } - ret = check_binary_integrity(NETTLE_LIBRARY_NAME, "nettle_aes_set_encrypt_key"); - if (ret == 0) { + if (!check_binary_integrity(NETTLE_LIBRARY_NAME, + "nettle_aes_set_encrypt_key")) { gnutls_assert(); goto error; } - ret = check_binary_integrity(HOGWEED_LIBRARY_NAME, "nettle_mpz_sizeinbase_256_u"); - if (ret == 0) { + if (!check_binary_integrity(HOGWEED_LIBRARY_NAME, + "nettle_mpz_sizeinbase_256_u")) { gnutls_assert(); goto error; } - ret = check_binary_integrity(GMP_LIBRARY_NAME, "__gmpz_init"); - if (ret == 0) { + if (!check_binary_integrity(GMP_LIBRARY_NAME, "__gmpz_init")) { gnutls_assert(); goto error; } diff --git a/lib/system.h b/lib/system.h index e15c8cd33dee354bc9b04940dc46c16bee4f6c58..a469530de2556e25c92bd29690d626d70dff5b3d 100644 --- a/lib/system.h +++ b/lib/system.h @@ -44,12 +44,6 @@ extern CertEnumCRLsInStoreFunc pCertEnumCRLsInStore; #include /* for writev */ #endif -#ifdef _POSIX_PATH_MAX -# define GNUTLS_PATH_MAX _POSIX_PATH_MAX -#else -# define GNUTLS_PATH_MAX 256 -#endif - int system_errno(gnutls_transport_ptr_t); ssize_t system_write(gnutls_transport_ptr_t ptr, const void *data, diff --git a/lib/system/certs.c b/lib/system/certs.c index 611c645e0517d4f96d354315b08f1d5ed0e632a1..5ff0d13f418cb05a26b0bdb530dbe1629ac00c84 100644 --- a/lib/system/certs.c +++ b/lib/system/certs.c @@ -223,22 +223,25 @@ static int load_revoked_certs(gnutls_x509_trust_list_t list, unsigned type) struct dirent *d; int ret; int r = 0; - char path[GNUTLS_PATH_MAX]; + char *path; dirp = opendir("/data/misc/keychain/cacerts-removed/"); if (dirp != NULL) { do { d = readdir(dirp); if (d != NULL && d->d_type == DT_REG) { - snprintf(path, sizeof(path), - "/data/misc/keychain/cacerts-removed/%s", - d->d_name); + if (asprintf(&path, + "/data/misc/keychain/cacerts-removed/%s", + d->d_name) < 0) { + continue; + } ret = gnutls_x509_trust_list_remove_trust_file (list, path, type); if (ret >= 0) r += ret; + free(path); } } while (d != NULL); diff --git a/lib/x509/verify-high2.c b/lib/x509/verify-high2.c index 16d757cf8a67f9cf919250fbadeb72a2e7bee4af..0b7fc41e8e7242b3352dd0b25a743b658d1f78d2 100644 --- a/lib/x509/verify-high2.c +++ b/lib/x509/verify-high2.c @@ -393,7 +393,7 @@ int load_dir_certs(const char *dirname, { int ret; int r = 0; - char path[GNUTLS_PATH_MAX]; + char *path; #if !defined(_WIN32) || !defined(_UNICODE) DIR *dirp; @@ -406,8 +406,9 @@ int load_dir_certs(const char *dirname, if (d->d_type == DT_REG || d->d_type == DT_LNK || d->d_type == DT_UNKNOWN) #endif { - snprintf(path, sizeof(path), "%s/%s", - dirname, d->d_name); + if (asprintf(&path, "%s/%s", dirname, d->d_name) < 0) { + continue; + } if (crl != 0) { ret = @@ -422,6 +423,7 @@ int load_dir_certs(const char *dirname, } if (ret >= 0) r += ret; + free(path); } } closedir(dirp); @@ -447,8 +449,9 @@ int load_dir_certs(const char *dirname, if (d->d_type == DT_REG || d->d_type == DT_LNK || d->d_type == DT_UNKNOWN) #endif { - snprintf(path, sizeof(path), "%s/%ls", - dirname, d->d_name); + if (asprintf(&path, "%s/%ls", dirname, d->d_name) < 0) { + continue; + } if (crl != 0) { ret = @@ -463,6 +466,7 @@ int load_dir_certs(const char *dirname, } if (ret >= 0) r += ret; + free(path); } } _tclosedir(dirp);