FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
checksum.c
Go to the documentation of this file.
1 /************************************************************
2  Copyright (C) 2007-2011 Hewlett-Packard Development Company, L.P.
3 
4  This program is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public License
6  version 2 as published by the Free Software Foundation.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License along
14  with this program; if not, write to the Free Software Foundation, Inc.,
15  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 
17  ************************************************************/
18 
19 #include <gcrypt.h>
20 
21 #include "checksum.h"
22 
38 CksumFile * SumOpenFile (char *Fname)
39 {
40  CksumFile *CF;
41  struct stat Stat;
42 
43  CF=(CksumFile *)calloc(1,sizeof(CksumFile));
44  if (!CF) return(NULL);
45 
46  /* open the file (memory map) */
47 #ifdef O_LARGEFILE
48  CF->FileHandle = open(Fname,O_RDONLY|O_LARGEFILE);
49 #else
50  /* BSD does not need nor use O_LARGEFILE */
51  CF->FileHandle = open(Fname,O_RDONLY);
52 #endif
53  if (CF->FileHandle == -1)
54  {
55  LOG_ERROR("Unable to open file (%s)\n",Fname);
56  free(CF);
57  return(NULL);
58  }
59  if (fstat(CF->FileHandle,&Stat) == -1)
60  {
61  LOG_ERROR("Unable to stat file (%s)\n",Fname);
62  close(CF->FileHandle);
63  free(CF);
64  return(NULL);
65  }
66  CF->MmapSize = Stat.st_size;
67  CF->MmapOffset = 0;
68 
69  /* reject files that are too long */
70  if (CF->MmapSize >= (uint32_t)(-1))
71  {
72  close(CF->FileHandle);
73  free(CF);
74  return(NULL);
75  }
76 
77  if (CF->MmapSize > 0)
78  {
79  CF->Mmap = mmap(0,CF->MmapSize,PROT_READ,MAP_PRIVATE,CF->FileHandle,0);
80  if (CF->Mmap == MAP_FAILED)
81  {
82  LOG_ERROR("Unable to mmap file (%s)\n",Fname);
83  close(CF->FileHandle);
84  free(CF);
85  return(NULL);
86  }
87  }
88  return(CF);
89 } /* SumOpenFile() */
90 
96 {
97  if ((CF->MmapSize > 0) && CF->Mmap) munmap(CF->Mmap,CF->MmapSize);
98  CF->MmapSize = 0;
99  CF->Mmap = NULL;
100  close(CF->FileHandle);
101  free(CF);
102 } /* SumCloseFile() */
103 
109 int CountDigits (uint64_t Num)
110 {
111  uint64_t Val=10;
112  int Digits=1;
113  for(Val=10; (Val > 0) && (Val < Num); Val = Val * 10)
114  {
115  Digits++;
116  }
117  return(Digits);
118 } /* CountDigits() */
119 
127 Cksum * SumComputeFile (FILE *Fin)
128 {
129  gcry_md_hd_t checksumhandler;
130  gcry_error_t checksumError = 0;
131  char Buffer[64];
132  Cksum *Sum;
133  unsigned char *tempBuff;
134  int ReadLen;
135  uint64_t ReadTotalLen=0;
136 
137  Sum = (Cksum *)calloc(1,sizeof(Cksum));
138  if (!Sum) return(NULL);
139 
140  checksumError = gcry_md_open(&checksumhandler, GCRY_MD_NONE, 0);
141  if (! checksumhandler)
142  {
143  LOG_ERROR("Unable to initialize checksum\n");
144  free(Sum);
145  return(NULL);
146  }
147  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_MD5);
148  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
149  {
150  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
151  gcry_strerror(checksumError));
152  free(Sum);
153  return(NULL);
154  }
155 
156  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_SHA1);
157  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
158  {
159  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
160  gcry_strerror(checksumError));
161  free(Sum);
162  return(NULL);
163  }
164 
165  while(!feof(Fin))
166  {
167  ReadLen = fread(Buffer,1,64,Fin);
168  if (ReadLen > 0)
169  {
170  gcry_md_write(checksumhandler, Buffer, ReadLen);
171  ReadTotalLen += ReadLen;
172  }
173  }
174 
175  Sum->DataLen = ReadTotalLen;
176 
177  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_MD5);
178  memcpy(Sum->MD5digest, tempBuff, sizeof(Sum->MD5digest));
179 
180  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_SHA1);
181  memcpy(Sum->SHA1digest, tempBuff, sizeof(Sum->SHA1digest));
182  gcry_md_close(checksumhandler);
183 
184  return(Sum);
185 } /* SumComputeFile() */
186 
195 {
196  Cksum *Sum;
197  gcry_md_hd_t checksumhandler;
198  gcry_error_t checksumError;
199  unsigned char *tempBuff;
200 
201  checksumError = gcry_md_open(&checksumhandler, GCRY_MD_NONE, 0);
202  if (! checksumhandler)
203  {
204  LOG_ERROR("Unable to initialize checksum\n");
205  return(NULL);
206  }
207  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_MD5);
208  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
209  {
210  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
211  gcry_strerror(checksumError));
212  return(NULL);
213  }
214 
215  checksumError = gcry_md_enable(checksumhandler, GCRY_MD_SHA1);
216  if (gcry_err_code(checksumError) != GPG_ERR_NO_ERROR)
217  {
218  LOG_ERROR("GCRY Error: %s/%s\n", gcry_strsource(checksumError),
219  gcry_strerror(checksumError));
220  return(NULL);
221  }
222 
223  Sum = (Cksum *)calloc(1,sizeof(Cksum));
224  if (!Sum)
225  {
226  return(NULL);
227  }
228  Sum->DataLen = CF->MmapSize;
229 
230  gcry_md_write(checksumhandler, CF->Mmap, CF->MmapSize);
231 
232  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_MD5);
233  memcpy(Sum->MD5digest, tempBuff, sizeof(Sum->MD5digest));
234 
235  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_SHA1);
236  memcpy(Sum->SHA1digest, tempBuff, sizeof(Sum->SHA1digest));
237 
238  gcry_md_close(checksumhandler);
239  return(Sum);
240 } /* SumComputeBuff() */
241 
242 
249 char * SumToString (Cksum *Sum)
250 {
251  int i;
252  char *Result;
253 
254  Result = (char *)calloc(1,16*2 +1+ 20*2 +1+ CountDigits(Sum->DataLen) + 1);
255  if (!Result) return(NULL);
256 
257  for(i=0; i<20; i++)
258  {
259  sprintf(Result + (i*2),"%02X",Sum->SHA1digest[i]);
260  }
261  Result[40]='.';
262  for(i=0; i<16; i++)
263  {
264  sprintf(Result + 41 + (i*2),"%02X",Sum->MD5digest[i]);
265  }
266  Result[41+32]='.';
267  sprintf(Result + 33 + 41,"%Lu",(long long unsigned int)Sum->DataLen);
268  return(Result);
269 } /* SumToString() */
270 
271 int calc_sha256sum(char*filename, char* dst) {
272  gcry_md_hd_t checksumhandler;
273  unsigned char buf[32];
274  unsigned char *tempBuff;
275  memset(buf, '\0', sizeof(buf));
276  FILE *f;
277  if(!(f=fopen(filename, "rb")))
278  {
279  LOG_FATAL("Failed to open file '%s'\n", filename);
280  return(1);
281  }
282  gcry_md_open(&checksumhandler, GCRY_MD_SHA256, 0);
283  if (! checksumhandler ||
284  (! gcry_md_is_enabled(checksumhandler, GCRY_MD_SHA256)))
285  {
286  LOG_ERROR("Unable to initialize checksum\n");
287  return(2);
288  }
289 
290  int i=0;
291  while((i=fread(buf, 1, sizeof(buf), f)) > 0) {
292  gcry_md_write(checksumhandler, buf, i);
293  }
294  fclose(f);
295  memset(buf, '\0', sizeof(buf));
296  tempBuff = gcry_md_read(checksumhandler, GCRY_MD_SHA256);
297  memcpy(buf, tempBuff, sizeof(buf));
298 
299  gcry_md_close(checksumhandler);
300 
301  for (i=0; i<32; i++)
302  {
303  snprintf(dst+i*2, 3, "%02X", buf[i]);
304  }
305 
306  return 0;
307 }
static int Result
Result of calls.
Definition: test_CopyFile.c:28
CksumFile * SumOpenFile(char *Fname)
Open and mmap a file.
Definition: checksum.c:38
Cksum * SumComputeFile(FILE *Fin)
Compute the checksum, allocate and return a string containing the sum value.
Definition: checksum.c:127
uint8_t SHA1digest[20]
SHA1 digest of the file.
Definition: checksum.h:42
int CountDigits(uint64_t Num)
Count how many digits are in a number.
Definition: checksum.c:109
uint8_t MD5digest[16]
MD5 digest of the file.
Definition: checksum.h:41
unsigned char * Mmap
Mmap of the file.
Definition: checksum.h:53
Store check sum of a file.
Definition: checksum.h:39
uint64_t DataLen
Size of the file.
Definition: checksum.h:43
char * SumToString(Cksum *Sum)
Return string representing a Cksum. NOTE: The calling function must free() the string! ...
Definition: checksum.c:249
uint64_t MmapSize
Size of mmap.
Definition: checksum.h:54
void SumCloseFile(CksumFile *CF)
Close a file that was opened with SumOpenFile()
Definition: checksum.c:95
Cksum * SumComputeBuff(CksumFile *CF)
Compute the checksum, allocate and return a Cksum containing the sum value.
Definition: checksum.c:194
int FileHandle
File handler for the file.
Definition: checksum.h:52
Store file handler and mmap of a file.
Definition: checksum.h:50