/* ================================================================================ RPL/2 (R) version 4.1.32 Copyright (C) 1989-2020 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 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 CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Calcul des sommes de contrôle avant le lancement d'un exécutable de la famille RPL/2 (rpliconv, rplconvert, rplfile et rplpp). ================================================================================ Entrée : - chaîne de caractères sur le fichier à contrôler - chaîne de caractères contenant la somme à contrôler - type de somme de contrôle -------------------------------------------------------------------------------- Sortie : drapeau -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ logical1 controle(struct_processus *s_etat_processus, unsigned char *fichier, unsigned char *type, unsigned char *somme_candidate) { EVP_MD_CTX *contexte; int in_fd; logical1 drapeau; off_t taille_fichier; ssize_t octets_lus; struct stat stat_buf; unsigned char *chaine; unsigned char *registre; unsigned char somme[EVP_MAX_MD_SIZE]; unsigned char somme_hexadecimale[2 * EVP_MAX_MD_SIZE]; unsigned int i; unsigned int longueur_somme; registre = fichier; # ifdef OS2 unsigned char *tampon; if ((tampon = malloc((strlen(fichier) + 5) * sizeof(unsigned char))) == NULL) { (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_faux); } sprintf(tampon, "%s.exe", fichier); fichier = tampon; # endif if (stat(fichier, &stat_buf) != 0) { # ifdef OS2 free(fichier); # endif (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } taille_fichier = stat_buf.st_size; if ((chaine = malloc((size_t) taille_fichier)) == NULL) { # ifdef OS2 free(fichier); # endif (*s_etat_processus).erreur_systeme = d_es_allocation_memoire; return(d_faux); } if ((in_fd = open(fichier, 0, O_RDONLY)) < 0) { # ifdef OS2 free(fichier); # endif free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } # ifdef OS2 free(fichier); # endif if ((octets_lus = read(in_fd, chaine, (size_t) taille_fichier)) != (ssize_t) taille_fichier) { # ifndef OS2 close(in_fd); free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); # endif } close(in_fd); if ((contexte = EVP_MD_CTX_new()) == NULL) { close(in_fd); return(d_faux); } if (strcmp(type, "md5") == 0) { if (EVP_DigestInit(contexte, EVP_md5()) != 1) { EVP_MD_CTX_free(contexte); close(in_fd); free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } if (EVP_DigestUpdate(contexte, chaine, (size_t) taille_fichier) != 1) { EVP_MD_CTX_free(contexte); close(in_fd); free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } if (EVP_DigestFinal_ex(contexte, somme, &longueur_somme) != 1) { EVP_MD_CTX_free(contexte); close(in_fd); free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } } else if (strcmp(type, "sha1") == 0) { if (EVP_DigestInit(contexte, EVP_sha1()) != 1) { EVP_MD_CTX_free(contexte); close(in_fd); free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } if (EVP_DigestUpdate(contexte, chaine, (size_t) taille_fichier) != 1) { EVP_MD_CTX_free(contexte); close(in_fd); free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } if (EVP_DigestFinal_ex(contexte, somme, &longueur_somme) != 1) { EVP_MD_CTX_free(contexte); close(in_fd); free(chaine); (*s_etat_processus).erreur_systeme = d_es_erreur_fichier; return(d_faux); } } else { return(d_faux); } EVP_MD_CTX_free(contexte); free(chaine); for(i = 0; i < longueur_somme; i++) { sprintf(&(somme_hexadecimale[2 * i]), "%02x", somme[i]); } if (strcmp(somme_candidate, somme_hexadecimale) == 0) { drapeau = d_vrai; } else { if ((*s_etat_processus).langue == 'F') { printf("+++Fatal : Somme de contrôle invalide\n"); printf("Fonction %s(%s)\n", type, registre); printf("Résultat obtenu : %s\n", somme_hexadecimale); printf("Résultat attendu : %s\n", somme_candidate); } else { printf("+++Fatal : Hash code mismatch\n"); printf("Function %s(%s)\n", type, registre); printf("Computed hash code : %s\n", somme_hexadecimale); printf("Expected hash code : %s\n", somme_candidate); } drapeau = d_faux; } return(drapeau); } // vim: ts=4