FOSSology  4.6.0
Open Source License Compliance by Open Source Software
checksum.c
Go to the documentation of this file.
1 /*
2  SPDX-FileCopyrightText: © 2007-2011 Hewlett-Packard Development Company, L.P.
3 
4  SPDX-License-Identifier: GPL-2.0-only
5 */
6 
7 #include <gcrypt.h>
8 
9 #include "checksum.h"
10 
26 CksumFile * SumOpenFile (char *Fname)
27 {
28  CksumFile *CF;
29  struct stat Stat;
30 
31  CF=(CksumFile *)calloc(1,sizeof(CksumFile));
32  if (!CF) return(NULL);
33 
34  /* open the file (memory map) */
35 #ifdef O_LARGEFILE
36  CF->FileHandle = open(Fname,O_RDONLY|O_LARGEFILE);
37 #else
38  /* BSD does not need nor use O_LARGEFILE */
39  CF->FileHandle = open(Fname,O_RDONLY);
40 #endif
41  if (CF->FileHandle == -1)
42  {
43  LOG_ERROR("Unable to open file (%s)\n",Fname);
44  free(CF);
45  return(NULL);
46  }
47  if (fstat(CF->FileHandle,&Stat) == -1)
48  {
49  LOG_ERROR("Unable to stat file (%s)\n",Fname);
50  close(CF->FileHandle);
51  free(CF);
52  return(NULL);
53  }
54  CF->MmapSize = Stat.st_size;
55  CF->MmapOffset = 0;
56 
57  /* reject files that are too long */
58  if (CF->MmapSize >= (uint32_t)(-1))
59  {
60  close(CF->FileHandle);
61  free(CF);
62  return(NULL);
63  }
64 
65  if (CF->MmapSize > 0)
66  {
67  CF->Mmap = mmap(0,CF->MmapSize,PROT_READ,MAP_PRIVATE,CF->FileHandle,0);
68  if (CF->Mmap == MAP_FAILED)
69  {
70  LOG_ERROR("Unable to mmap file (%s)\n",Fname);
71  close(CF->FileHandle);
72  free(CF);
73  return(NULL);
74  }
75  }
76  return(CF);
77 } /* SumOpenFile() */
78 
84 {
85  if ((CF->MmapSize > 0) && CF->Mmap) munmap(CF->Mmap,CF->MmapSize);
86  CF->MmapSize = 0;
87  CF->Mmap = NULL;
88  close(CF->FileHandle);
89  free(CF);
90 } /* SumCloseFile() */
91 
97 int CountDigits (uint64_t Num)
98 {
99  uint64_t Val=10;
100  int Digits=1;
101  for(Val=10; (Val > 0) && (Val < Num); Val = Val * 10)
102  {
103  Digits++;
104  }
105  return(Digits);
106 } /* CountDigits() */
107 
115 Cksum * SumComputeFile (FILE *Fin)
116 {
117  gcry_md_hd_t checksumhandler;
118  gcry_error_t checksumError = 0;
119  char Buffer[64];
120  Cksum *Sum;
121  unsigned char *tempBuff;
122  int ReadLen;
123  uint64_t ReadTotalLen=0;
124 
125  Sum = (Cksum *)calloc(1,sizeof(Cksum));
126  if (!Sum) return(NULL);
127 
128  checksumError = gcry_md_open(&checksumhandler, GCRY_MD_NONE, 0);
129  if (! checksumhandler)
130  {
131  LOG_ERROR("Unable to initialize checksum\n");
132  free(Sum);
133  return(NULL);
134  }
135  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_MD5);
136  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
137  {
138  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
139  gcry_strerror(checksumError));
140  free(Sum);
141  return(NULL);
142  }
143 
144  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_SHA1);
145  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
146  {
147  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
148  gcry_strerror(checksumError));
149  free(Sum);
150  return(NULL);
151  }
152 
153  while(!feof(Fin))
154  {
155  ReadLen = fread(Buffer,1,64,Fin);
156  if (ReadLen > 0)
157  {
158  gcry_md_write(checksumhandler, Buffer, ReadLen);
159  ReadTotalLen += ReadLen;
160  }
161  }
162 
163  Sum->DataLen = ReadTotalLen;
164 
165  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_MD5);
166  memcpy(Sum->MD5digest, tempBuff, sizeof(Sum->MD5digest));
167 
168  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_SHA1);
169  memcpy(Sum->SHA1digest, tempBuff, sizeof(Sum->SHA1digest));
170  gcry_md_close(checksumhandler);
171 
172  return(Sum);
173 } /* SumComputeFile() */
174 
183 {
184  Cksum *Sum;
185  gcry_md_hd_t checksumhandler;
186  gcry_error_t checksumError;
187  unsigned char *tempBuff;
188 
189  checksumError = gcry_md_open(&checksumhandler, GCRY_MD_NONE, 0);
190  if (! checksumhandler)
191  {
192  LOG_ERROR("Unable to initialize checksum\n");
193  return(NULL);
194  }
195  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_MD5);
196  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
197  {
198  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
199  gcry_strerror(checksumError));
200  gcry_md_close(checksumhandler);
201  return(NULL);
202  }
203 
204  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_SHA1);
205  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
206  {
207  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
208  gcry_strerror(checksumError));
209  gcry_md_close(checksumhandler);
210  return(NULL);
211  }
212 
213  Sum = (Cksum *)calloc(1,sizeof(Cksum));
214  if (!Sum)
215  {
216  gcry_md_close(checksumhandler);
217  return(NULL);
218  }
219  Sum->DataLen = CF->MmapSize;
220 
221  gcry_md_write(checksumhandler, CF->Mmap, CF->MmapSize);
222 
223  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_MD5);
224  memcpy(Sum->MD5digest, tempBuff, sizeof(Sum->MD5digest));
225 
226  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_SHA1);
227  memcpy(Sum->SHA1digest, tempBuff, sizeof(Sum->SHA1digest));
228 
229  gcry_md_close(checksumhandler);
230  return(Sum);
231 } /* SumComputeBuff() */
232 
233 
240 char * SumToString (Cksum *Sum)
241 {
242  int i;
243  char *Result;
244 
245  Result = (char *)calloc(1,16*2 +1+ 20*2 +1+ CountDigits(Sum->DataLen) + 1);
246  if (!Result) return(NULL);
247 
248  for(i=0; i<20; i++)
249  {
250  sprintf(Result + (i*2),"%02X",Sum->SHA1digest[i]);
251  }
252  Result[40]='.';
253  for(i=0; i<16; i++)
254  {
255  sprintf(Result + 41 + (i*2),"%02X",Sum->MD5digest[i]);
256  }
257  Result[41+32]='.';
258  sprintf(Result + 33 + 41,"%Lu",(long long unsigned int)Sum->DataLen);
259  return(Result);
260 } /* SumToString() */
261 
262 int calc_sha256sum(char*filename, char* dst) {
263  gcry_md_hd_t checksumhandler;
264  unsigned char buf[32];
265  unsigned char *tempBuff;
266  memset(buf, '\0', sizeof(buf));
267  FILE *f;
268  if(!(f=fopen(filename, "rb")))
269  {
270  LOG_FATAL("Failed to open file '%s'\n", filename);
271  return(1);
272  }
273  gcry_md_open(&checksumhandler, GCRY_MD_SHA256, 0);
274  if (! checksumhandler ||
275  (! gcry_md_is_enabled(checksumhandler, GCRY_MD_SHA256)))
276  {
277  LOG_ERROR("Unable to initialize checksum\n");
278  return(2);
279  }
280 
281  int i=0;
282  while((i=fread(buf, 1, sizeof(buf), f)) > 0) {
283  gcry_md_write(checksumhandler, buf, i);
284  }
285  fclose(f);
286  memset(buf, '\0', sizeof(buf));
287  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_SHA256);
288  memcpy(buf, tempBuff, sizeof(buf));
289 
290  gcry_md_close(checksumhandler);
291 
292  for (i=0; i<32; i++)
293  {
294  snprintf(dst+i*2, 3, "%02X", buf[i]);
295  }
296 
297  return 0;
298 }
char * SumToString(Cksum *Sum)
Return string representing a Cksum. NOTE: The calling function must free() the string!
Definition: checksum.c:240
Cksum * SumComputeBuff(CksumFile *CF)
Compute the checksum, allocate and return a Cksum containing the sum value.
Definition: checksum.c:182
int CountDigits(uint64_t Num)
Count how many digits are in a number.
Definition: checksum.c:97
Cksum * SumComputeFile(FILE *Fin)
Compute the checksum, allocate and return a string containing the sum value.
Definition: checksum.c:115
CksumFile * SumOpenFile(char *Fname)
Open and mmap a file.
Definition: checksum.c:26
void SumCloseFile(CksumFile *CF)
Close a file that was opened with SumOpenFile()
Definition: checksum.c:83
Store file handler and mmap of a file.
Definition: checksum.h:44
int FileHandle
File handler for the file.
Definition: checksum.h:45
unsigned char * Mmap
Mmap of the file.
Definition: checksum.h:46
uint64_t MmapSize
Size of mmap.
Definition: checksum.h:47
uint64_t MmapOffset
Index into mmap.
Definition: checksum.h:48
Store check sum of a file.
Definition: checksum.h:33
uint8_t SHA1digest[20]
SHA1 digest of the file.
Definition: checksum.h:35
uint64_t DataLen
Size of the file.
Definition: checksum.h:36
uint8_t MD5digest[16]
MD5 digest of the file.
Definition: checksum.h:34
static int Result
Result of calls.
Definition: test_CopyFile.c:17