/******************************************************************************
*
* autor: Daniel Lerch
*
* Referencias:
* Network security with OpenSSL (O'Reilly)
* [Adaptacion de un ejemplo del libro para multiples algoritmos hash]
*
* Compilacion:
* $ gcc digest.c -o digest -lssl
*
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <openssl/evp.h>
#define READSIZE 1024
unsigned char *simple_digest (char *alg,
char *buffer,
unsigned int len,
int *olen)
{
EVP_MD *m;
EVP_MD_CTX ctx;
unsigned char *ret;
OpenSSL_add_all_digests ();
if (!(m = (EVP_MD*) EVP_get_digestbyname (alg)))
return NULL;
if (!(ret = (unsigned char *) malloc (EVP_MAX_MD_SIZE)))
return NULL;
EVP_DigestInit (&ctx, m);
EVP_DigestUpdate (&ctx, buffer, len);
EVP_DigestFinal (&ctx, ret, olen);
return ret;
}
void print_hex (unsigned char *bs, unsigned int n)
{
int i;
for (i = 0; i < n; i++)
printf ("%02x", bs[i]);
}
unsigned char *read_file (FILE * f, int *len)
{
unsigned char *buffer = NULL, *last = NULL;
unsigned char inbuffer[READSIZE];
int tot, n;
tot = 0;
for (;;)
{
n = fread (inbuffer, sizeof (unsigned char), READSIZE, f);
if (n > 0)
{
last = buffer;
buffer = (unsigned char *) malloc (tot + n);
memcpy (buffer, last, tot);
memcpy (&buffer[tot], inbuffer, n);
if (last)
free (last);
tot += n;
if (feof (f) > 0)
{
*len = tot;
return buffer;
}
}
else
{
if (buffer)
free (buffer);
break;
}
}
return NULL;
}
unsigned char *process_file (char *algorithm, FILE * f, unsigned int *olen)
{
int filelen;
unsigned char *ret, *contents = read_file (f, &filelen);
if (!contents)
return NULL;
ret = simple_digest (algorithm, contents, filelen, olen);
free (contents);
return ret;
}
int process_stdin (char *algorithm)
{
unsigned int olen;
unsigned char *digest = process_file (algorithm, stdin, &olen);
if (!digest)
return 0;
print_hex (digest, olen);
printf ("\n");
free(digest);
return 1;
}
void usage (char *progname) {
printf ("Usage: %s [ md2 | md4 | md5 | sha | sha1 ] [ Files ] \n\n",
progname);
exit(0);
}
int main (int argc, char *argv[])
{
int i;
/* Sin parametros */
if (argc < 2) usage(argv[0]);
/* Verificamos los algoritmos */
if ( (strcmp(argv[1], "md2") != 0) &&
(strcmp(argv[1], "md4") != 0) &&
(strcmp(argv[1], "md5") != 0) &&
(strcmp(argv[1], "sha") != 0) &&
(strcmp(argv[1], "sha1") != 0) ) usage(argv[0]);
/* Un solo parametro, entrada estandar */
if (argc == 2) { if (!process_stdin (argv[1])) perror ("stdin"); }
/* Lee y procesa todos los parametros recibidos */
else {
for (i = 2; i < argc; i++) {
FILE *file = fopen (argv[i], "rb");
unsigned int olen;
unsigned char *digest;
if (!file) { perror (argv[i]); return -1; }
digest = process_file (argv[1], file, &olen);
if (!digest) {
fclose (file);
return -1;
}
fclose (file);
print_hex (digest, olen);
printf (" %s\n", argv[i]);
free(digest);
}
}
return 1;
}
|