/*
http://ardoino.altervista.org/crypto-security/articles/openssl_all
*/
//-------------------hash.c----------------------------------------------
#include <openssl/md5.h>
#include <openssl/evp.h>

void make_hex(u_char *in, u_char *out)
{
    const char    *hex = "0123456789abcdef";
    int i;

    for(i = 0; i < 16; i++, in++) {
        *out++ = hex[*in >> 4];
        *out++ = hex[*in & 0xf];
    }
    *out = 0x00;
    return;
}

/* MD5
 * Hashing algorithm
 * md5hash() performs the hash of a given file. 
 */
void md5hash(char *filein)
{
   FILE *fp = NULL;
   unsigned int tmpsize=0,linesize=0;
   char *hashbuf = NULL;
   unsigned char *hash = NULL;
   EVP_MD_CTX ctx;

   printf("MD5 hash of '%s' file is:\n",filein);
   EVP_DigestInit(&ctx,EVP_md5()); /* initializes digest context*/
   fp = fopen(filein,"r");
   while ((linesize = getline(&hashbuf,&tmpsize,fp)) != -1) {
      EVP_DigestUpdate(&ctx,hashbuf,linesize); /* hashes 
      linesize bytes of data at hashbuf */
      linesize = 0;
   }
   fclose(fp);
   hash = (unsigned char *)malloc(16);
   EVP_DigestFinal(&ctx,(unsigned char *)hash,NULL); /* retrieves
   the digest value */
   make_hex(hash, hashbuf);
   printf("%s\n",hashbuf);
   free(hashbuf);
   free(hash);
   return;
}

/* MD5
 * Hashing algorithm
 * md5cmp() compares the hash of two given files.
 */
void md5cmp(char *file1, char *file2)
{
   FILE *fp = NULL;
   unsigned int tmpsize=0,linesize=0;
   char *hashbuf = NULL;
   unsigned char *hash1 = NULL, *hash2 = NULL;
   EVP_MD_CTX ctx;

   printf("Comparing MD5 hashes of '%s' and '%s' files.\n",\
   file1,file2);
   EVP_DigestInit(&ctx,EVP_md5());
   fp = fopen(file1,"r");
   while ((linesize = getline(&hashbuf,&tmpsize,fp)) != -1) {
      EVP_DigestUpdate(&ctx,hashbuf,linesize);
      linesize = 0;
   }
   fclose(fp);
   hash1 = (unsigned char *)malloc(16);
   EVP_DigestFinal(&ctx,(unsigned char *)hash1,NULL);
   EVP_DigestInit(&ctx,EVP_md5()); /* initializes the digest 
   context */
   linesize = 0;
   tmpsize = 0;
   fp = fopen(file2, "r");
   while ((linesize = getline(&hashbuf,&tmpsize,fp)) != -1) {
      EVP_DigestUpdate(&ctx,hashbuf,linesize); /* hashes 
      linesize bytes of data at hashbuf */
      linesize = 0;
   }
   fclose(fp);
   hash2 = (unsigned char *)malloc(16);
   EVP_DigestFinal(&ctx,(unsigned char *)hash2,NULL); /* retrieves
   the digest value */
   if (strcmp(hash1,hash2) == 0)
     printf("MD5 hashes match.\n");
   else
     printf("MD5 hashes don't match.\n");
   free(hash1);
   free(hash2);
   free(hashbuf);
   return;
}
//-------------------end hash.c------------------------------------------