diff --git a/configure.ac b/configure.ac
index 39a445cd..f40c3678 100644
--- a/configure.ac
+++ b/configure.ac
@@ -9,8 +9,6 @@
 	  AC_PROG_LIBTOOL
 	  AC_C_INLINE
 	  AM_PROG_CC_C_O
-	  AC_SEARCH_LIBS([json_object_from_file], [json json-c], [], [ AC_MSG_ERROR([no available json library]) ])
-	  AC_SEARCH_LIBS([json_object_object_get_ex], [json json-c], [ AC_DEFINE([JSON_HAS_GET_EX], [1], [Define if we have json_object_object_get_ex])], [])
   	  AC_CHECK_FUNCS([localtime_r])
 	  AC_CHECK_FUNCS([dup2])
 	  AC_CHECK_FUNCS([getcwd])
@@ -61,7 +59,6 @@
 	  AC_CHECK_HEADERS([time.h])
 	  AC_CHECK_HEADERS([sys/ioctl.h])
 	  AC_CHECK_HEADERS([sys/time.h])
-	  AC_CHECK_HEADERS([json/json.h])
 	  AC_CHECK_HEADERS([glib.h])
 	  AC_CHECK_HEADERS([gio/gio.h])
 	  AC_CHECK_HEADERS([asm/opal-prd.h])
diff --git a/src/lib/include/fwts.h b/src/lib/include/fwts.h
index 1e0d5870..6f13d262 100644
--- a/src/lib/include/fwts.h
+++ b/src/lib/include/fwts.h
@@ -153,6 +153,8 @@
 
 #define FWTS_JSON_DATA_PATH	DATAROOTDIR "/fwts"
 
+#include <inttypes.h>
+
 #include "fwts_version.h"
 #include "fwts_backtrace.h"
 #include "fwts_types.h"
diff --git a/src/lib/include/fwts_json.h b/src/lib/include/fwts_json.h
index ad51bc45..0c316e02 100644
--- a/src/lib/include/fwts_json.h
+++ b/src/lib/include/fwts_json.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2020 Canonical
+ * Copyright (C) 2010-2020 Canonical
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -16,26 +16,15 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  */
-
 #ifndef __FWTS_JSON_H__
 #define __FWTS_JSON_H__
 
-#include <json.h>
-
-#define __FWTS_JSON_ERR_PTR__ ((json_object*) -1)
 /*
- *  Older versions of json-c may return an error in an
- *  object as a ((json_object*)-1), where as newer
- *  versions return NULL, so check for these. Sigh.
+ *  Minimal subset of json for fwts
  */
-#define FWTS_JSON_ERROR(ptr) \
-	( (ptr == NULL) || ((const json_object *)ptr == __FWTS_JSON_ERR_PTR__) )
 
-/*
- * json-c 0.13.99 does not define TRUE/FALSE anymore
- * the json-c maintainers replaced them with pure 1/0
- * https://github.com/json-c/json-c/commit/0992aac61f8b
- */
+#define FWTS_JSON_ERROR(ptr) 	(!ptr)
+
 #ifndef FALSE
 #define FALSE 0
 #endif
@@ -44,4 +33,46 @@
 #define TRUE  1
 #endif
 
+/*
+ *  json types supported
+ */
+typedef enum {
+	type_null,
+	type_int,
+	type_string,
+	type_object,
+	type_array,
+} json_type;
+
+/*
+ *  json object information
+ */
+typedef struct json_object {
+	char *key;		/* Null if undefined */
+	int length;		/* Length of a collection of objects */
+	json_type type;		/* Object type */
+        union {
+                void *ptr;	/* string or object array pointer */
+                int  intval;	/* integer value */
+        } u;
+} json_object;
+
+/*
+ *  minimal json c library functions as required by fwts
+ */
+json_object *json_object_from_file(const char *filename);
+json_object *json_object_object_get(json_object *obj, const char *key);
+int json_object_array_length(json_object *obj);
+json_object *json_object_array_get_idx(json_object *obj, int index);
+const char *json_object_get_string(json_object *obj);
+json_object *json_object_new_int(int);
+void json_object_object_add(json_object *obj, const char *key, json_object *value);
+
+json_object *json_object_new_object(void);
+json_object *json_object_new_array(void);
+char *json_object_to_json_string(json_object *obj);
+void json_object_put(json_object *obj);
+json_object *json_object_new_string(const char *str);
+int json_object_array_add(json_object *obj, json_object *item);
+
 #endif
diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am
index ecc4136b..4593bb82 100644
--- a/src/lib/src/Makefile.am
+++ b/src/lib/src/Makefile.am
@@ -82,6 +82,7 @@ libfwts_la_SOURCES = 		\
 	fwts_interactive.c 	\
 	fwts_ioport.c		\
 	fwts_ipmi.c		\
+	fwts_json.c		\
 	fwts_keymap.c 		\
 	fwts_klog.c 		\
 	fwts_olog.c		\
diff --git a/src/lib/src/fwts_json.c b/src/lib/src/fwts_json.c
new file mode 100644
index 00000000..b92a241a
--- /dev/null
+++ b/src/lib/src/fwts_json.c
@@ -0,0 +1,917 @@
+/*
+ * Copyright (C) 2010-2020 Canonical
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * This is a simplified json parser and json object store
+ * based on json but does not support keywords and is designed
+ * just for the fwts json data files. It is not a full json
+ * implementation and should not be used as such.
+ *
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#include "fwts.h"
+
+/*
+ *  json file information
+ */
+typedef struct {
+	FILE *fp;		/* File pointer */
+	const char *filename;	/* Name of file */
+	int linenum;		/* Parser line number */
+	int charnum;		/* Parser char position */
+	int error_reported;	/* Error count */
+} json_file;
+
+/*
+ *  json tokens, subset of full json token set as used
+ *  for fwts requirements
+ */
+typedef enum {
+	token_lbrace,
+	token_rbrace,
+	token_lbracket,
+	token_rbracket,
+	token_colon,
+	token_comma,
+	token_int,
+	token_string,
+	token_true,
+	token_false,
+	token_null,
+	token_error,
+	token_eof,
+} json_token_type;
+
+/*
+ *  json parser token
+ */
+typedef struct {
+	json_token_type type;	/* token type */
+	long offset;		/* offset in file for re-winding */
+	union {
+		char *str;	/* token string value */
+		int  intval;	/* token integer value */
+	} u;
+} json_token;
+
+/*
+ *  json_token_string()
+ *	convert json token to a human readable string
+ */
+char *json_token_string(json_token *jtoken)
+{
+	static char tmp[64];
+
+	switch (jtoken->type) {
+	case token_lbrace:
+		return "{";
+	case token_rbrace:
+		return "}";
+	case token_lbracket:
+		return "[";
+	case token_rbracket:
+		return "]";
+	case token_colon:
+		return ":";
+	case token_comma:
+		return ",";
+	case token_int:
+		(void)snprintf(tmp, sizeof(tmp), "%d", jtoken->u.intval);
+		return tmp;
+	case token_string:
+		return jtoken->u.str;
+	case token_error:
+		return "<error>";
+	case token_eof:
+		return "end of file";
+	default:
+		break;
+	}
+	return "<illegal token>";
+}
+
+/*
+ *  json_get_string()
+ *	parse a literal string
+ */
+json_token_type json_get_string(json_file *jfile, json_token *token)
+{
+	char buffer[4096];
+	size_t i = 0;
+
+	for (;;) {
+		int ch;
+
+		ch = fgetc(jfile->fp);
+		jfile->charnum++;
+		if (ch == EOF) {
+			fprintf(stderr, "json_parser: unexpected EOF in literal string\n");
+			token->u.str = NULL;
+			return token_error;
+		}
+
+		if (ch == '\\') {
+			ch = fgetc(jfile->fp);
+			switch (ch) {
+			case '\\':
+			case '"':
+			case '/':
+				break;
+			case 'b':
+				ch = '\b';
+				break;
+			case 'f':
+				ch = '\f';
+				break;
+			case 'n':
+				ch = '\n';
+				break;
+			case 'r':
+				ch = '\r';
+				break;
+			case 't':
+				ch = '\t';
+				break;
+			case 'u':
+				fprintf(stderr, "json parser: escaped hex values not supported\n");
+				ch = '?';
+				break;
+			}
+			jfile->charnum++;
+		} else if (ch == '"') {
+			buffer[i] = '\0';
+			token->u.str = strdup(buffer);
+			if (!token->u.str) {
+				fprintf(stderr, "json parser: out of memory allocating %zd byte string\n", i);
+				break;
+			}
+			return token_string;
+		}
+		buffer[i] = ch;
+		i++;
+		if (i >= sizeof(buffer)) {
+			fprintf(stderr, "json parser: string too long, maximum size %zd bytes\n", sizeof(buffer) - 1);
+			break;
+		}
+	}
+
+	token->u.str = NULL;
+	return token_error;
+}
+
+/*
+ *  json_get_int()
+ *	parse a simple integer
+ */
+json_token_type json_get_int(json_file *jfile, json_token *token)
+{
+	char buffer[64];
+	size_t i = 0;
+
+	for (;;) {
+		int ch;
+
+		ch = fgetc(jfile->fp);
+		if (!isdigit(ch)) {
+			(void)ungetc(ch, jfile->fp);
+			buffer[i] = '\0';
+			token->u.intval = atoi(buffer);
+			return token_int;
+		}
+		jfile->charnum++;
+		buffer[i] = ch;
+		i++;
+		if (i >= sizeof(buffer)) {
+			fprintf(stderr, "json parser: integer too long, maximum size %zd bytes\n", sizeof(buffer) - 1);
+			break;
+		}
+	}
+
+	token->u.str = NULL;
+	return token_error;
+}
+
+/*
+ *  json_unget_token()
+ *  	push file pointer back to point before the token
+ *	to unpush the token
+ */
+int json_unget_token(json_file *jfile, json_token *token)
+{
+	return fseek(jfile->fp, token->offset, SEEK_SET);
+}
+
+/*
+ *  json_get_keyword()
+ *	get a keyword
+ */
+int json_get_keyword(json_file *jfile, json_token *token)
+{
+	char buffer[32];
+	size_t i = 0;
+
+	token->u.str = NULL;
+	*buffer = '\0';
+
+	for (;;) {
+		int ch;
+
+		ch = fgetc(jfile->fp);
+		jfile->charnum++;
+		if (ch == EOF) {
+			fprintf(stderr, "json_parser: unexpected EOF in keyword string\n");
+			return token_error;
+		}
+		if (ch < 'a' || ch > 'z')
+			break;
+
+		buffer[i] = ch;
+		i++;
+		if (i >= sizeof(buffer)) {
+			fprintf(stderr, "json parser: keyword too long, maximum size %zd bytes\n", sizeof(buffer) - 1);
+			return token_error;
+		}
+	}
+	if (!strcmp(buffer, "true"))
+		return token_true;
+	if (!strcmp(buffer, "false"))
+		return token_false;
+	if (!strcmp(buffer, "null"))
+		return token_null;
+	return token_error;
+}
+
+/*
+ *  json_get_token()
+ *	read next input character(s) and return a matching token
+ */
+json_token_type json_get_token(json_file *jfile, json_token *token)
+{
+	(void)memset(token, 0, sizeof(*token));
+
+	token->offset = ftell(jfile->fp);
+	for (;;) {
+		int ch;
+
+		ch = fgetc(jfile->fp);
+		jfile->charnum++;
+
+		switch (ch) {
+		case '\n':
+			jfile->linenum++;
+			continue;
+		case ' ':
+		case '\r':
+		case '\t':
+			continue;
+		case EOF:
+			token->type = token_eof;
+			return token->type;
+		case '{':
+			token->type = token_lbrace;
+			return token->type;
+		case '}':
+			token->type = token_rbrace;
+			return token->type;
+		case '[':
+			token->type = token_lbracket;
+			return token->type;
+		case ']':
+			token->type = token_rbracket;
+			return token->type;
+		case ':':
+			token->type = token_colon;
+			return token->type;
+		case ',':
+			token->type = token_comma;
+			return token->type;
+		case '"':
+			token->type = json_get_string(jfile, token);
+			return token->type;
+		case '0'...'9':
+			token->type = json_get_int(jfile, token);
+			return token->type;
+		case 'a'...'z':
+			fprintf(stderr, "json_parser: keywords not supported\n");
+			token->type = token_error;
+			return token->type;
+		default:
+			token->type = token_error;
+			return token->type;
+		}
+	}
+
+	/* Should never reach here */
+	token->type = token_error;
+	return token->type;
+}
+
+/*
+ *  json_parse_error_where()
+ *	very simple parser error message, report where in the file
+ *	the parsing error occurred.
+ */
+void json_parse_error_where(json_file *jfile)
+{
+	if (jfile->error_reported == 0)
+		fprintf(stderr, "json_parser: aborted at line %d, char %d of file %s\n",
+			jfile->linenum, jfile->charnum, jfile->filename);
+	jfile->error_reported++;
+}
+
+json_object *json_parse_object(json_file *jfile);
+
+/*
+ *  json_parse_array()
+ *	parse a json array
+ */
+json_object *json_parse_array(json_file *jfile)
+{
+	json_object *array_obj;
+
+	array_obj = json_object_new_array();
+	if (!array_obj) {
+		fprintf(stderr, "json_parser: out of memory allocating a json array object\n");
+		json_parse_error_where(jfile);
+		return NULL;
+	}
+
+	for (;;) {
+		json_object *obj;
+		json_token token;
+
+		obj = json_parse_object(jfile);
+		if (!obj) {
+			json_parse_error_where(jfile);
+			free(array_obj);
+			return NULL;
+		}
+		json_object_array_add(array_obj, obj);
+
+		switch (json_get_token(jfile, &token)) {
+		case token_rbracket:
+			return array_obj;
+		case token_comma:
+			continue;
+		default:
+			if (json_unget_token(jfile, &token) != 0) {
+				fprintf(stderr, "json_parser: failed to unget a token\n");
+				free(array_obj);
+				return NULL;
+			}
+			break;
+		}
+	}
+	return array_obj;
+}
+
+/*
+ *  json_parse_object()
+ *	parse a json object (simplified fwts json format only)
+ */
+json_object *json_parse_object(json_file *jfile)
+{
+	json_token token;
+	json_object *obj, *val_obj;
+	char *key = NULL;
+
+	if (json_get_token(jfile, &token) != token_lbrace) {
+		fprintf(stderr, "json_parser: expecting '{', got %s instead\n", json_token_string(&token));
+		return NULL;
+	}
+
+	obj = json_object_new_object();
+	if (!obj)
+		goto err_nomem;
+
+	for (;;) {
+		switch (json_get_token(jfile, &token)) {
+		case token_rbrace:
+			return obj;
+		case token_string:
+			key = token.u.str;
+			if (!key)
+				goto err_nomem;
+			token.u.str = NULL;
+			break;
+		default:
+			fprintf(stderr, "json_parser: expecting } or key literal string, got %s instead\n", json_token_string(&token));
+			goto err_free;
+		}
+		if (json_get_token(jfile, &token) != token_colon) {
+			fprintf(stderr, "json_parser: expecting ':', got %s instead\n", json_token_string(&token));
+			goto err_free;
+		}
+		switch (json_get_token(jfile, &token)) {
+		case token_string:
+			val_obj = json_object_new_string(token.u.str);
+			if (!val_obj)
+				goto err_nomem;
+			json_object_object_add(obj, key, val_obj);
+			free(key);
+			break;
+		case token_int:
+			val_obj = json_object_new_int(token.u.intval);
+			if (!val_obj)
+				goto err_nomem;
+			json_object_object_add(obj, key, val_obj);
+			free(key);
+			break;
+		case token_lbracket:
+			val_obj = json_parse_array(jfile);
+			if (!val_obj)
+				goto err_nomem;
+			json_object_object_add(obj, key, val_obj);
+			break;
+		case token_lbrace:
+			fprintf(stderr, "json_parser: nested objects not supported\n");
+			goto err_free;
+		case token_true:
+		case token_false:
+		case token_null:
+			fprintf(stderr, "json_parser: tokens %s not supported\n", json_token_string(&token));
+			goto err_free;
+		default:
+			fprintf(stderr, "json_parser: unexpected token %s\n", json_token_string(&token));
+		}
+		switch (json_get_token(jfile, &token)) {
+		case token_comma:
+			continue;
+		case token_rbrace:
+			return obj;
+		default:
+			fprintf(stderr, "json_parser: expected , or }, got %s instead\n", json_token_string(&token));
+			goto err_free;
+		}
+	}
+
+err_nomem:
+	fprintf(stderr, "json_parser: out of memory allocating a json object\n");
+	json_parse_error_where(jfile);
+err_free:
+	free(obj);
+	return NULL;
+}
+
+/*
+ *  json_object_from_file()
+ *	parse a simplified fwts json file and convert it into
+ *	a json object, return NULL if parsing failed or ran
+ *	out of memory
+ */
+json_object *json_object_from_file(const char *filename)
+{
+	json_object *obj;
+	json_file jfile;
+
+	jfile.filename = filename;
+	jfile.linenum = 1;
+	jfile.charnum = 0;
+	jfile.error_reported = 0;
+
+	jfile.fp = fopen(filename, "r");
+	if (!jfile.fp)
+		return NULL;
+
+	obj = json_parse_object(&jfile);
+
+	fclose(jfile.fp);
+	return obj;
+}
+
+/*
+ *  json_object_new_object()
+ *	return a new json object, NULL if failed
+ */
+json_object *json_object_new_object(void)
+{
+	json_object *obj;
+
+	obj = calloc(1, sizeof(*obj));
+	if (!obj)
+		return NULL;
+	obj->type = type_object;
+	obj->u.ptr = NULL;
+
+	return obj;
+}
+
+/*
+ *  json_object_new_object()
+ *	return a new json object, NULL if failed
+ */
+int json_object_array_length(json_object *obj)
+{
+	if (!obj)
+		return 0;
+	if (obj->type != type_array)
+		return 0;
+	return obj->length;
+}
+
+/*
+ *  json_object_new_int()
+ *	return a new json integer object, NULL if failed
+ */
+json_object *json_object_new_int(int val)
+{
+	json_object *obj;
+
+	obj = calloc(1, sizeof(*obj));
+	if (!obj)
+		return NULL;
+	obj->type = type_int;
+	obj->u.intval = val;
+
+	return obj;
+}
+
+/*
+ *  json_object_new_string()
+ *	return a new json string object, NULL if failed
+ */
+json_object *json_object_new_string(const char *str)
+{
+	json_object *obj;
+
+	obj = calloc(1, sizeof(*obj));
+	if (!obj)
+		return NULL;
+	obj->type = type_string;
+	obj->u.ptr = strdup(str);
+	if (!obj->u.ptr) {
+		free(obj);
+		return NULL;
+	}
+	return obj;
+}
+
+/*
+ *  json_object_new_array()
+ *	return a new json array object, NULL if failed
+ */
+json_object *json_object_new_array(void)
+{
+	json_object *obj;
+
+	obj = calloc(1, sizeof(*obj));
+	if (!obj)
+		return NULL;
+	obj->type = type_array;
+	obj->length = 0;
+	obj->u.ptr = NULL;
+
+	return obj;
+}
+
+/*
+ *  json_object_array_add_item()
+ *	add an object to another object, return 0 if succeeded,
+ *	non-zero if failed
+ */
+static int json_object_array_add_item(json_object *obj, json_object *item)
+{
+	json_object **obj_ptr;
+
+	if (obj->length < 0)
+		return -1;
+	obj_ptr = realloc(obj->u.ptr, sizeof(json_object *) * (obj->length + 1));
+	if (!obj_ptr)
+		return -1;
+	obj->u.ptr = (void *)obj_ptr;
+	obj_ptr[obj->length] = item;
+	obj->length++;
+	return 0;
+}
+
+/*
+ *  json_object_array_add()
+ *	add a object to a json array object, return NULL if failed
+ */
+int json_object_array_add(json_object *obj, json_object *item)
+{
+	if (!obj || !item)
+		return -1;
+	if (obj->type != type_array)
+		return -1;
+	return json_object_array_add_item(obj, item);
+}
+
+
+/*
+ *  json_object_object_add()
+ *	add a key/valyue object to a json object, return NULL if failed
+ */
+void json_object_object_add(json_object *obj, const char *key, json_object *value)
+{
+	if (!obj || !key || !value)
+		return;
+	if (obj->type != type_object)
+		return;
+	value->key = strdup(key);
+	if (!value->key)
+		return;
+	json_object_array_add_item(obj, value);
+}
+
+/*
+ *  json_object_array_get_idx()
+ *	get an object at position index from a json array object,
+ *	return NULL if failed
+ */
+json_object *json_object_array_get_idx(json_object *obj, int index)
+{
+	json_object **obj_array;
+
+	if (!obj)
+		return NULL;
+	if (obj->type != type_array)
+		return NULL;
+	if (index >= obj->length)
+		return NULL;
+	obj_array = (json_object **)obj->u.ptr;
+	if (obj_array == NULL)
+		return NULL;
+	return obj_array[index];
+}
+
+/*
+ *  json_object_get_string()
+ *	return a C string from a json string object
+ */
+const char *json_object_get_string(json_object *obj)
+{
+	if (!obj)
+		return NULL;
+	if (obj->type != type_string)
+		return NULL;
+	return (const char *)obj->u.ptr;
+}
+
+/*
+ *  json_object_put()
+ *	free a json object and all sub-objects
+ */
+void json_object_put(json_object *obj)
+{
+	int i;
+	json_object **obj_ptr;
+
+	if (!obj)
+		return;
+
+	if (obj->key)
+		free(obj->key);
+
+	switch (obj->type) {
+	case type_array:
+	case type_object:
+		obj_ptr = (json_object **)obj->u.ptr;
+
+		for (i = 0; i < obj->length; i++) {
+			json_object_put(obj_ptr[i]);
+		}
+		free(obj->u.ptr);
+		break;
+	case type_string:
+		free(obj->u.ptr);
+		break;
+	case type_null:
+	case type_int:
+	default:
+		break;
+	}
+	free(obj);
+}
+
+/*
+ *  str_append()
+ *	append a string to a string, return NULL if failed
+ */
+static char *str_append(char *str, char *append)
+{
+	char *new_str;
+	size_t len;
+
+	if (!append)
+		return NULL;
+
+	if (str) {
+		len = strlen(append) + strlen(str) + 1;
+		new_str = realloc(str, len);
+		if (!new_str) {
+			free(str);
+			return NULL;
+		}
+		strcat(new_str, append);
+	} else {
+		len = strlen(append) + 1;
+		new_str = malloc(len);
+		if (!new_str)
+			return NULL;
+		strcpy(new_str, append);
+	}
+	return new_str;
+}
+
+/*
+ *  str_indent()
+ *	add 2 spaces per indent level to a string, returns
+ *	NULL if failed
+ */
+static char *str_indent(char *str, int indent)
+{
+	char buf[81];
+	int i;
+
+	indent = indent + indent;
+	if (indent > 80)
+		indent = 80;
+
+	for (i = 0; i < indent; i++)
+		buf[i] = ' ';
+	buf[i] = '\0';
+
+	return str_append(str, buf);
+}
+
+/*
+ *  json_object_to_json_string_indent()
+ *	turn a simplified fwts json object into a C string, returns
+ *	the stringified object or NULL if failed. Will traverse object
+ *	tree and add indentation based on recursion depth.
+ */
+static char *json_object_to_json_string_indent(json_object *obj, int indent)
+{
+	int i;
+	json_object **obj_ptr;
+	char *str = NULL;
+	char buf[64];
+
+	if (!obj)
+		return NULL;
+
+	if (obj->type == type_object) {
+		str = str_indent(str, indent);
+		if (!str)
+			return NULL;
+		str = str_append(str, "{\n");
+		if (!str)
+			return NULL;
+	}
+
+        if (obj->key) {
+		str = str_indent(str, indent);
+		if (!str)
+			return NULL;
+		str = str_append(str, "\"");
+		if (!str)
+			return NULL;
+		str = str_append(str, obj->key);
+		if (!str)
+			return NULL;
+		str = str_append(str, "\":");
+		if (!str)
+			return NULL;
+        }
+
+	switch (obj->type) {
+	case type_array:
+		str = str_append(str, "[\n");
+		if (!str)
+			return NULL;
+
+		obj_ptr = (json_object **)obj->u.ptr;
+		if (obj_ptr) {
+			for (i = 0; i < obj->length; i++) {
+				char *obj_str = json_object_to_json_string_indent(obj_ptr[i], indent + 1);
+
+				if (!obj_str) {
+					free(str);
+					return NULL;
+				}
+				str = str_append(str, obj_str);
+				if (!str)
+					return NULL;
+			}
+		}
+		str = str_append(str, "\n");
+		if (!str)
+			return NULL;
+		str = str_indent(str, indent);
+		if (!str)
+			return NULL;
+		str = str_append(str, "]\n");
+		if (!str)
+			return NULL;
+		break;
+
+	case type_object:
+		obj_ptr = (json_object **)obj->u.ptr;
+		if (obj_ptr) {
+			for (i = 0; i < obj->length; i++) {
+				char *obj_str = json_object_to_json_string_indent(obj_ptr[i], indent + 1);
+
+				if (!obj_str)
+					return NULL;
+				str = str_append(str, obj_str);
+				if (!str)
+					return NULL;
+			}
+		}
+		if (!str)
+			return NULL;
+		break;
+
+	case type_string:
+		str = str_append(str, "\"");
+		if (!str)
+			return NULL;
+		str = str_append(str, (char *)obj->u.ptr);
+		if (!str)
+			return NULL;
+		str = str_append(str, "\",\n");
+		if (!str)
+			return NULL;
+		break;
+
+	case type_null:
+		str = str_append(str, "(null)\n");
+		if (!str)
+			return NULL;
+		break;
+
+	case type_int:
+		snprintf(buf, sizeof(buf), "%d,\n", obj->u.intval);
+		str = str_append(str, buf);
+		if (!str)
+			return NULL;
+		break;
+	default:
+		return NULL;
+	}
+
+	if (obj->type == type_object) {
+		str = str_indent(str, indent);
+		if (!str)
+			return NULL;
+		str = str_append(str, "},\n");
+		if (!str)
+			return NULL;
+	}
+	return str;
+}
+
+/*
+ *  json_object_to_json_string
+ *	convert simplified fwts object to a C string, returns
+ *	NULL if failed
+ */
+char *json_object_to_json_string(json_object *obj)
+{
+	return json_object_to_json_string_indent(obj, 0);
+}
+
+/*
+ *  json_object_object_get()
+ *	return value from key/value pair from an object, returns
+ *	NULL if it can't be found
+ */
+json_object *json_object_object_get(json_object *obj, const char *key)
+{
+	int i;
+	json_object **obj_ptr;
+
+	if (!obj || !key)
+		return NULL;
+	if (obj->type != type_object)
+		return NULL;
+
+	obj_ptr = (json_object **)obj->u.ptr;
+	for (i = 0; i < obj->length; i++) {
+		if (obj_ptr[i]->key && !strcmp(obj_ptr[i]->key, key))
+			return obj_ptr[i];
+	}
+	return NULL;
+}
+
diff --git a/src/utilities/Makefile.am b/src/utilities/Makefile.am
index 98d6ebaa..2ae86038 100644
--- a/src/utilities/Makefile.am
+++ b/src/utilities/Makefile.am
@@ -18,10 +18,11 @@
 
 AM_CPPFLAGS = -Wall -Werror -Wextra -DDATAROOTDIR=\"$(datarootdir)\" \
 	`pkg-config --silence-errors --cflags json` \
-	`pkg-config --silence-errors --cflags json-c`
+	`pkg-config --silence-errors --cflags json-c` \
+	-I../lib/include
 
 bin_PROGRAMS = kernelscan
-kernelscan_SOURCES = kernelscan.c
+kernelscan_SOURCES = kernelscan.c ../lib/src/fwts_json.c
 
 
 -include $(top_srcdir)/git.mk
diff --git a/src/utilities/kernelscan.c b/src/utilities/kernelscan.c
index 2e68ef33..49ffe5c1 100644
--- a/src/utilities/kernelscan.c
+++ b/src/utilities/kernelscan.c
@@ -21,11 +21,12 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stddef.h>
 #include <ctype.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <regex.h>
-#include <json.h>
+#include "fwts_json.h"
 
 #include "config.h"
 
