VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTDigest.cpp@ 23501

Last change on this file since 23501 was 23501, checked in by vboxsync, 15 years ago

IPRT: Added SHA-1, SHA-256 and SHA-512 APIs. Added a simple digest program for testing these.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.8 KB
Line 
1/* $Id: tstRTDigest.cpp 23501 2009-10-02 10:59:42Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTSha*, RTMd5, RTCrc*.
4 */
5
6/*
7 * Copyright (C) 2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include <iprt/sha.h>
36#include <iprt/md5.h>
37#include <iprt/crc32.h>
38#include <iprt/crc64.h>
39
40#include <iprt/ctype.h>
41#include <iprt/err.h>
42#include <iprt/file.h>
43#include <iprt/getopt.h>
44#include <iprt/initterm.h>
45#include <iprt/param.h>
46#include <iprt/path.h>
47#include <iprt/process.h>
48#include <iprt/string.h>
49#include <iprt/stream.h>
50
51
52static int Error(const char *pszFormat, ...)
53{
54 char szName[RTPATH_MAX];
55 if (!RTProcGetExecutableName(szName, sizeof(szName)))
56 strcpy(szName, "tstRTDigest");
57
58 RTStrmPrintf(g_pStdErr, "%s: error: ", RTPathFilename(szName));
59 va_list va;
60 va_start(va, pszFormat);
61 RTStrmPrintfV(g_pStdErr, pszFormat, va);
62 va_end(va);
63
64 return 1;
65}
66
67
68int main(int argc, char **argv)
69{
70 RTR3Init();
71
72 enum
73 {
74 kDigestType_NotSpecified,
75 kDigestType_CRC32,
76 kDigestType_CRC64,
77 kDigestType_MD5,
78 kDigestType_SHA1,
79 kDigestType_SHA256,
80 kDigestType_SHA512
81 } enmDigestType = kDigestType_NotSpecified;
82
83 enum
84 {
85 kMethod_Full,
86 kMethod_Block,
87 kMethod_File
88 } enmMethod = kMethod_Block;
89
90 static const RTGETOPTDEF s_aOptions[] =
91 {
92 { "--type", 't', RTGETOPT_REQ_STRING },
93 { "--method", 'm', RTGETOPT_REQ_STRING },
94 { "--help", 'h', RTGETOPT_REQ_NOTHING },
95 };
96
97 int ch;
98 RTGETOPTUNION ValueUnion;
99 RTGETOPTSTATE GetState;
100 RTGetOptInit(&GetState, argc, argv, s_aOptions, RT_ELEMENTS(s_aOptions), 1, 0);
101 while ((ch = RTGetOpt(&GetState, &ValueUnion)))
102 {
103 switch (ch)
104 {
105 case 't':
106 if (!RTStrICmp(ValueUnion.psz, "crc32"))
107 enmDigestType = kDigestType_CRC32;
108 else if (!RTStrICmp(ValueUnion.psz, "crc64"))
109 enmDigestType = kDigestType_CRC64;
110 else if (!RTStrICmp(ValueUnion.psz, "md5"))
111 enmDigestType = kDigestType_MD5;
112 else if (!RTStrICmp(ValueUnion.psz, "sha1"))
113 enmDigestType = kDigestType_SHA1;
114 else if (!RTStrICmp(ValueUnion.psz, "sha256"))
115 enmDigestType = kDigestType_SHA256;
116 else if (!RTStrICmp(ValueUnion.psz, "sha512"))
117 enmDigestType = kDigestType_SHA512;
118 else
119 {
120 Error("Invalid digest type: %s\n", ValueUnion.psz);
121 return 1;
122 }
123 break;
124
125 case 'm':
126 if (!RTStrICmp(ValueUnion.psz, "full"))
127 enmMethod = kMethod_Full;
128 else if (!RTStrICmp(ValueUnion.psz, "block"))
129 enmMethod = kMethod_Block;
130 else if (!RTStrICmp(ValueUnion.psz, "file"))
131 enmMethod = kMethod_File;
132 else
133 {
134 Error("Invalid digest method: %s\n", ValueUnion.psz);
135 return 1;
136 }
137 break;
138
139 case 'h':
140 RTPrintf("syntax: tstRTDigest -t <digest-type> file [file2 [..]]\n");
141 return 1;
142
143 case VINF_GETOPT_NOT_OPTION:
144 {
145 if (enmDigestType == kDigestType_NotSpecified)
146 return Error("No digest type was specified\n");
147
148 switch (enmMethod)
149 {
150 case kMethod_Full:
151 return Error("Full file method is not implemented\n");
152
153 case kMethod_File:
154 switch (enmDigestType)
155 {
156 case kDigestType_SHA1:
157 {
158 char *pszDigest;
159 int rc = RTSha1Digest(ValueUnion.psz, &pszDigest);
160 if (RT_FAILURE(rc))
161 return Error("RTSha1Digest(%s,) -> %Rrc\n", ValueUnion.psz, rc);
162 RTPrintf("%s %s\n", pszDigest, ValueUnion.psz);
163 RTStrFree(pszDigest);
164 break;
165 }
166
167 default:
168 return Error("The file method isn't implemented for this digest\n");
169 }
170 break;
171
172 case kMethod_Block:
173 {
174 RTFILE hFile;
175 int rc = RTFileOpen(&hFile, ValueUnion.psz, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_WRITE);
176 if (RT_FAILURE(rc))
177 return Error("RTFileOpen(,%s,) -> %Rrc\n", ValueUnion.psz, rc);
178
179 size_t cbRead;
180 uint8_t abBuf[_64K];
181 char *pszDigest = (char *)&abBuf[0];
182 switch (enmDigestType)
183 {
184 case kDigestType_CRC32:
185 {
186 uint32_t uCRC32 = RTCrc32Start();
187 for (;;)
188 {
189 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
190 if (RT_FAILURE(rc) || !cbRead)
191 break;
192 uCRC32 = RTCrc32Process(uCRC32, abBuf, cbRead);
193 }
194 uCRC32 = RTCrc32Finish(uCRC32);
195 RTStrPrintf(pszDigest, sizeof(abBuf), "%08RX32", uCRC32);
196 break;
197 }
198
199 case kDigestType_CRC64:
200 {
201 uint64_t uCRC64 = RTCrc64Start();
202 for (;;)
203 {
204 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
205 if (RT_FAILURE(rc) || !cbRead)
206 break;
207 uCRC64 = RTCrc64Process(uCRC64, abBuf, cbRead);
208 }
209 uCRC64 = RTCrc64Finish(uCRC64);
210 RTStrPrintf(pszDigest, sizeof(abBuf), "%016RX64", uCRC64);
211 break;
212 }
213
214 case kDigestType_MD5:
215 {
216 RTMD5CONTEXT Ctx;
217 RTMd5Init(&Ctx);
218 for (;;)
219 {
220 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
221 if (RT_FAILURE(rc) || !cbRead)
222 break;
223 RTMd5Update(&Ctx, abBuf, cbRead);
224 }
225 uint8_t abDigest[RTMD5HASHSIZE];
226 RTMd5Final(abDigest, &Ctx);
227 RTStrPrintf(pszDigest, sizeof(abBuf),
228 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
229 abDigest[0], abDigest[1], abDigest[2], abDigest[3],
230 abDigest[4], abDigest[5], abDigest[6], abDigest[7],
231 abDigest[8], abDigest[9], abDigest[10], abDigest[11],
232 abDigest[12], abDigest[13], abDigest[14], abDigest[15]);
233 break;
234 }
235
236 case kDigestType_SHA1:
237 {
238 RTSHA1CONTEXT Ctx;
239 RTSha1Init(&Ctx);
240 for (;;)
241 {
242 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
243 if (RT_FAILURE(rc) || !cbRead)
244 break;
245 RTSha1Update(&Ctx, abBuf, cbRead);
246 }
247 uint8_t abDigest[RTSHA1_HASH_SIZE];
248 RTSha1Final(&Ctx, abDigest);
249 RTStrPrintf(pszDigest, sizeof(abBuf),
250 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
251 abDigest[0], abDigest[1], abDigest[2], abDigest[3],
252 abDigest[4], abDigest[5], abDigest[6], abDigest[7],
253 abDigest[8], abDigest[9], abDigest[10], abDigest[11],
254 abDigest[12], abDigest[13], abDigest[14], abDigest[15],
255 abDigest[16], abDigest[17], abDigest[18], abDigest[19]);
256 break;
257 }
258
259 case kDigestType_SHA256:
260 {
261 RTSHA256CONTEXT Ctx;
262 RTSha256Init(&Ctx);
263 for (;;)
264 {
265 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
266 if (RT_FAILURE(rc) || !cbRead)
267 break;
268 RTSha256Update(&Ctx, abBuf, cbRead);
269 }
270 uint8_t abDigest[RTSHA256_HASH_SIZE];
271 RTSha256Final(&Ctx, abDigest);
272 RTStrPrintf(pszDigest, sizeof(abBuf),
273 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
274 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
275 abDigest[0], abDigest[1], abDigest[2], abDigest[3],
276 abDigest[4], abDigest[5], abDigest[6], abDigest[7],
277 abDigest[8], abDigest[9], abDigest[10], abDigest[11],
278 abDigest[12], abDigest[13], abDigest[14], abDigest[15],
279 abDigest[16], abDigest[17], abDigest[18], abDigest[19],
280 abDigest[20], abDigest[21], abDigest[22], abDigest[23],
281 abDigest[24], abDigest[25], abDigest[26], abDigest[27],
282 abDigest[28], abDigest[29], abDigest[30], abDigest[31]);
283 break;
284 }
285
286 case kDigestType_SHA512:
287 {
288 RTSHA512CONTEXT Ctx;
289 RTSha512Init(&Ctx);
290 for (;;)
291 {
292 rc = RTFileRead(hFile, abBuf, sizeof(abBuf), &cbRead);
293 if (RT_FAILURE(rc) || !cbRead)
294 break;
295 RTSha512Update(&Ctx, abBuf, cbRead);
296 }
297 uint8_t abDigest[RTSHA512_HASH_SIZE];
298 RTSha512Final(&Ctx, abDigest);
299 RTStrPrintf(pszDigest, sizeof(abBuf),
300 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
301 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
302 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
303 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
304 abDigest[0], abDigest[1], abDigest[2], abDigest[3],
305 abDigest[4], abDigest[5], abDigest[6], abDigest[7],
306 abDigest[8], abDigest[9], abDigest[10], abDigest[11],
307 abDigest[12], abDigest[13], abDigest[14], abDigest[15],
308 abDigest[16], abDigest[17], abDigest[18], abDigest[19],
309 abDigest[20], abDigest[21], abDigest[22], abDigest[23],
310 abDigest[24], abDigest[25], abDigest[26], abDigest[27],
311 abDigest[28], abDigest[29], abDigest[30], abDigest[31],
312 abDigest[32], abDigest[33], abDigest[34], abDigest[35],
313 abDigest[36], abDigest[37], abDigest[38], abDigest[39],
314 abDigest[40], abDigest[41], abDigest[42], abDigest[43],
315 abDigest[44], abDigest[45], abDigest[46], abDigest[47],
316 abDigest[48], abDigest[49], abDigest[50], abDigest[51],
317 abDigest[52], abDigest[53], abDigest[54], abDigest[55],
318 abDigest[56], abDigest[57], abDigest[58], abDigest[59],
319 abDigest[60], abDigest[61], abDigest[62], abDigest[63]);
320 break;
321 }
322
323 default:
324 return Error("Internal error #1\n");
325 }
326 RTFileClose(hFile);
327 if (RT_FAILURE(rc) && rc != VERR_EOF)
328 {
329 RTPrintf("Partial: %s %s\n", pszDigest, ValueUnion.psz);
330 return Error("RTFileRead(%s) -> %Rrc\n", ValueUnion.psz, rc);
331 }
332 RTPrintf("%s %s\n", pszDigest, ValueUnion.psz);
333 break;
334 }
335
336 default:
337 return Error("Internal error #2\n");
338 }
339 break;
340 }
341
342 default:
343 if (ch > 0)
344 {
345 if (RT_C_IS_GRAPH(ch))
346 Error("unhandled option: -%c\n", ch);
347 else
348 Error("unhandled option: %i\n", ch);
349 }
350 else if (ch == VERR_GETOPT_UNKNOWN_OPTION)
351 Error("unknown option: %s\n", ValueUnion.psz);
352 else if (ValueUnion.pDef)
353 Error("%s: %Rrs\n", ValueUnion.pDef->pszLong, ch);
354 else
355 Error("%Rrs\n", ch);
356 return 1;
357 }
358 }
359
360 return 0;
361}
362
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette