Énigme #2: Chacun cherche son SHA1

Cette fois-ci, l’énigme est en langage C et porte sur l’utilisation de la bibliothèque OpenSSL.

Il y a quelques semaines, un ami m’a pointé un comportement étrange dans l’un de ses programmes. Le programme en question s’appuye sur la bibliothèque OpenSSL et calcule le SHA1 d’un fichier:

#include <stdio.h>
#include <stdlib.h>
#include <openssl/sha.h>
 
int
main (int argc, char **argv)
{
  char *content;
  SHA_CTX ctx;
  unsigned char message_digest[SHA_DIGEST_LENGTH];
  int retval;
  FILE *fh;
 
  /* SHA1 DIGEST */
  SHA1_Init (&ctx);
 
  fh = fopen (argv[1], "r");
  content = (char *) malloc (4096);
 
  while (!feof (fh))
    {
      retval = fread ((char *) content, 1, 4096, fh);
      printf ("Read:%d\n", retval);
      SHA1_Update (&ctx, content, retval);
    }
 
  SHA1_Final (message_digest, &ctx);
  puts ((char *) message_digest);
 
  free ((void *) content);
  fclose (fh);
 
  return EXIT_SUCCESS;
}

Tout semble marcher sur la plupart des fichiers, sauf que lorsqu’on essaye de calculer le SHA1 de fichier.bin, le programme ne semble rien faire…

Sauriez-vous expliquer pourquoi et surtout proposer une solution à ce problème ?

Cette entrée a été publiée dans Énigme, Programmation. Vous pouvez la mettre en favoris avec ce permalien.

3 réponses à Énigme #2: Chacun cherche son SHA1

  1. Firas Kraïem dit :

    C’est parce que le hash commence par un ‘\0‘, donc puts n’affiche rien. M’enfin c’est un peu tiré par les cheveux, je vois pas quelle est l’utilité de puts ici, étant donné que certains caractère seront non-ASCII.

    Pour simuler le comportement de l’outil sha1sum des GNU coreutils, on peut remplacer l’appel à puts par :

    for (int i=0; i < SHA_DIGEST_LENGTH; i++)
        printf ("%02x", message_digest[i]);
    printf ("  %s\n", argv[1]);
    • Aszarsha dit :

      En effet, c’est encore plus débile que ce que j’imaginais, c’est simplement la fonction d’affichage qui se prend un caractère invalide…

      À noter que ma remarque reste parfaitement pertinente, et un test vient de me confirmer qu’une lecture en mode texte de fichier.bin termine prématurément sous Windows (à la lecture du premier caractère EOF, que l’on peut insérer en mode text avec Ctrl+Z), le programme ne retournant alors évidement pas le bon hash.

    • Fleury dit :

      Oui, la cause du problème est effectivement un caractère ‘\0‘ dès le début du digest.

      Et ta réponse ressemble exactement à celle que j’ai en réserve:

      for (i = 0; i < SHA_DIGEST_LENGTH; i++)
          printf("%02x", message_digest[i]);
        printf("\n");