#include <unistd.h>
#include "errors.h"
#include "file.h"
-#include "inih/ini.h"
+#include "inih/ini.h"
#include <fips.h>
#include <gnutls/self-test.h>
#include <stdio.h>
if (fd != NULL) {
f1p = fgetc(fd);
fclose(fd);
-
+
if (f1p == '1') f1p = 1;
else f1p = 0;
}
#define HMAC_FILE_NAME ".gnutls.hmac"
#define HMAC_FORMAT_VERSION 1
+struct hmac_entry
+{
+ char path[GNUTLS_PATH_MAX];
+ uint8_t hmac[HMAC_SIZE];
+};
+
typedef struct
{
int version;
- char gnutls_path[GNUTLS_PATH_MAX];
- char nettle_path[GNUTLS_PATH_MAX];
- char hogweed_path[GNUTLS_PATH_MAX];
- char gmp_path[GNUTLS_PATH_MAX];
- uint8_t gnutls_hmac[HMAC_SIZE];
- uint8_t nettle_hmac[HMAC_SIZE];
- uint8_t hogweed_hmac[HMAC_SIZE];
- uint8_t gmp_hmac[HMAC_SIZE];
+ struct hmac_entry gnutls;
+ struct hmac_entry nettle;
+ struct hmac_entry hogweed;
+ struct hmac_entry gmp;
} hmac_file;
static int get_library_path(const char* lib, const char* symbol, char* path, size_t path_size)
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;
}
-
+
ret = snprintf(path, path_size, "%s", info.dli_fname);
if ((size_t)ret >= path_size) {
ret = gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER);
gnutls_datum_t data;
data.size = strlen(value);
- if (hex_data_size(data.size) != HMAC_SIZE)
- return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
-
- data.data = (uint8_t *)gnutls_strdup(value);
- if (data.data == NULL)
- return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+ data.data = value;
hmac_size = HMAC_SIZE;
ret = gnutls_hex_decode(&data, dest, &hmac_size);
- gnutls_free(data.data);
if (ret < 0)
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
return 0;
}
+static int
+lib_handler(struct hmac_entry *entry,
+ const char *section, const char *name, const char *value)
+{
+ if (!strcmp(name, "path")) {
+ snprintf(entry->path, GNUTLS_PATH_MAX, "%s", value);
+ } else if (!strcmp(name, "hmac")) {
+ if (get_hmac(entry->hmac, value) < 0)
+ return 0;
+ } else {
+ return 0;
+ }
+ return 1;
+}
+
static int handler(void *user, const char *section, const char *name, const char *value)
{
hmac_file *p = (hmac_file *)user;
return 0;
}
} else if (!strcmp(section, GNUTLS_LIBRARY_NAME)) {
- if (!strcmp(name, "path")) {
- snprintf(p->gnutls_path, GNUTLS_PATH_MAX, "%s", value);
- } else if (!strcmp(name, "hmac")) {
- if (get_hmac(p->gnutls_hmac, value) < 0)
- return 0;
- } else {
- return 0;
- }
+ return lib_handler(&p->gnutls, section, name, value);
} else if (!strcmp(section, NETTLE_LIBRARY_NAME)) {
- if (!strcmp(name, "path")) {
- snprintf(p->nettle_path, GNUTLS_PATH_MAX, "%s", value);
- } else if (!strcmp(name, "hmac")) {
- if (get_hmac(p->nettle_hmac, value) < 0)
- return 0;
- } else {
- return 0;
- }
+ return lib_handler(&p->nettle, section, name, value);
} else if (!strcmp(section, HOGWEED_LIBRARY_NAME)) {
- if (!strcmp(name, "path")) {
- snprintf(p->hogweed_path, GNUTLS_PATH_MAX, "%s", value);
- } else if (!strcmp(name, "hmac")) {
- if (get_hmac(p->hogweed_hmac, value) < 0)
- return 0;
- } else {
- return 0;
- }
+ return lib_handler(&p->hogweed, section, name, value);
} else if (!strcmp(section, GMP_LIBRARY_NAME)) {
- if (!strcmp(name, "path")) {
- snprintf(p->gmp_path, GNUTLS_PATH_MAX, "%s", value);
- } else if (!strcmp(name, "hmac")) {
- if (get_hmac(p->gmp_hmac, value) < 0)
- return 0;
- } else {
- return 0;
- }
+ return lib_handler(&p->gmp, section, name, value);
} else {
return 0;
}
return 0;
}
-static int check_lib_path(const char path[GNUTLS_PATH_MAX],
+/* Run an HMAC using the key above on the library binary data.
+ * Returns 0 on success and negative value on error.
+ */
+static int check_lib_hmac(struct hmac_entry *entry,
const char *lib, const char *sym)
{
int ret;
- char new_path[GNUTLS_PATH_MAX];
-
- ret = get_library_path(lib, sym, new_path, sizeof(new_path));
+ unsigned prev;
+ char path[GNUTLS_PATH_MAX];
+ uint8_t hmac[HMAC_SIZE];
+ gnutls_datum_t data;
+
+ ret = get_library_path(lib, sym, path, sizeof(path));
if (ret < 0) {
_gnutls_debug_log("Could not get lib path for %s: %s\n",
lib, gnutls_strerror(ret));
return gnutls_assert_val(ret);
}
- if (strncmp(path, new_path, GNUTLS_PATH_MAX)) {
+ if (strncmp(entry->path, path, GNUTLS_PATH_MAX)) {
_gnutls_debug_log("Library path for %s does not match with HMAC file\n", lib);
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
}
- return 0;
-}
-
-/* Run an HMAC using the key above on the library binary data.
- * Returns 0 on success and negative value on error.
- */
-static int check_lib_hmac(const char path[GNUTLS_PATH_MAX],
- const uint8_t hmac[HMAC_SIZE])
-{
- int ret;
- unsigned prev;
- uint8_t new_hmac[HMAC_SIZE];
- gnutls_datum_t data;
-
_gnutls_debug_log("Loading: %s\n", path);
ret = gnutls_load_file(path, &data);
if (ret < 0) {
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, hmac);
_gnutls_switch_lib_state(prev);
gnutls_free(data.data);
return gnutls_assert_val(ret);
}
- if (gnutls_memcmp(hmac, new_hmac, HMAC_SIZE)) {
+ if (gnutls_memcmp(entry->hmac, hmac, HMAC_SIZE)) {
_gnutls_debug_log("Calculated MAC for %s does not match\n", path);
return gnutls_assert_val(GNUTLS_E_PARSING_ERROR);
}
_gnutls_debug_log("Successfully verified MAC for %s\n", path);
-
+
return 0;
}
return ret;
}
- ret = check_lib_path(file.gnutls_path, GNUTLS_LIBRARY_NAME, "gnutls_global_init");
- if (ret < 0)
- return ret;
- ret = check_lib_hmac(file.gnutls_path, file.gnutls_hmac);
- if (ret < 0)
- return ret;
- ret = check_lib_path(file.nettle_path, NETTLE_LIBRARY_NAME, "nettle_aes_set_encrypt_key");
- if (ret < 0)
- return ret;
- ret = check_lib_hmac(file.nettle_path, file.nettle_hmac);
- if (ret < 0)
- return ret;
- ret = check_lib_path(file.hogweed_path, HOGWEED_LIBRARY_NAME, "nettle_mpz_sizeinbase_256_u");
+ ret = check_lib_hmac(&file.gnutls, GNUTLS_LIBRARY_NAME, "gnutls_global_init");
if (ret < 0)
return ret;
- ret = check_lib_hmac(file.hogweed_path, file.hogweed_hmac);
+ ret = check_lib_hmac(&file.nettle, NETTLE_LIBRARY_NAME, "nettle_aes_set_encrypt_key");
if (ret < 0)
return ret;
- ret = check_lib_path(file.gmp_path, GMP_LIBRARY_NAME, "__gmpz_init");
+ ret = check_lib_hmac(&file.hogweed, HOGWEED_LIBRARY_NAME, "nettle_mpz_sizeinbase_256_u");
if (ret < 0)
return ret;
- ret = check_lib_hmac(file.gmp_path, file.gmp_hmac);
+ ret = check_lib_hmac(&file.gmp, GMP_LIBRARY_NAME, "__gmpz_init");
if (ret < 0)
return ret;