Read file directly - simplified
You let the user pass in a char* but you don't use it. you might as well remove it and declare it as a local variable.

char *readFile (FILE* fp)
{
    char* source;


Some FILE* won't let you seek to the end (stdin and socket streams for example). You should check the return value of fseek and fall back to the classic fread then realloc, rinse and repeat method on error.

A single fread is more efficient than the repeated fgetc; so you can replace the while with:

int readBytes = fread(source, size, 1, fp);

string[readBytes] = '\0';