VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/checksum/RTSha256Digest.cpp@ 51701

Last change on this file since 51701 was 45234, checked in by vboxsync, 12 years ago

fix OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.8 KB
Line 
1/** @file
2 * IPRT - SHA256 digest creation
3 */
4
5/*
6 * Copyright (C) 2009-2013 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include "internal/iprt.h"
31#include <iprt/sha.h>
32
33#include <iprt/alloca.h>
34#include <iprt/assert.h>
35#include <iprt/mem.h>
36#include <iprt/string.h>
37#include <iprt/file.h>
38
39#include <openssl/sha.h>
40
41
42RTR3DECL(int) RTSha256Digest(void* pvBuf, size_t cbBuf, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
43{
44 /* Validate input */
45 AssertPtrReturn(pvBuf, VERR_INVALID_POINTER);
46 AssertPtrReturn(ppszDigest, VERR_INVALID_POINTER);
47 AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
48
49 int rc = VINF_SUCCESS;
50 *ppszDigest = NULL;
51
52 /* Initialize OpenSSL. */
53 SHA256_CTX ctx;
54 if (!SHA256_Init(&ctx))
55 return VERR_INTERNAL_ERROR;
56
57 /* Buffer size for progress callback */
58 double rdMulti = 100.0 / cbBuf;
59
60 /* Working buffer */
61 char *pvTmp = (char*)pvBuf;
62
63 /* Process the memory in blocks */
64 size_t cbRead;
65 size_t cbReadTotal = 0;
66 for (;;)
67 {
68 cbRead = RT_MIN(cbBuf - cbReadTotal, _1M);
69 if(!SHA256_Update(&ctx, pvTmp, cbRead))
70 {
71 rc = VERR_INTERNAL_ERROR;
72 break;
73 }
74 cbReadTotal += cbRead;
75 pvTmp += cbRead;
76
77 /* Call the progress callback if one is defined */
78 if (pfnProgressCallback)
79 {
80 rc = pfnProgressCallback((unsigned)(cbReadTotal * rdMulti), pvUser);
81 if (RT_FAILURE(rc))
82 break; /* canceled */
83 }
84 /* Finished? */
85 if (cbReadTotal == cbBuf)
86 break;
87 }
88 if (RT_SUCCESS(rc))
89 {
90 /* Finally calculate & format the SHA256 sum */
91 unsigned char auchDig[RTSHA256_HASH_SIZE];
92 if (!SHA256_Final(auchDig, &ctx))
93 return VERR_INTERNAL_ERROR;
94
95 char *pszDigest;
96 rc = RTStrAllocEx(&pszDigest, RTSHA256_DIGEST_LEN + 1);
97 if (RT_SUCCESS(rc))
98 {
99 rc = RTSha256ToString(auchDig, pszDigest, RTSHA256_DIGEST_LEN + 1);
100 if (RT_SUCCESS(rc))
101 *ppszDigest = pszDigest;
102 else
103 RTStrFree(pszDigest);
104 }
105 }
106
107 return rc;
108}
109
110RTR3DECL(int) RTSha256DigestFromFile(const char *pszFile, char **ppszDigest, PFNRTPROGRESS pfnProgressCallback, void *pvUser)
111{
112 /* Validate input */
113 AssertPtrReturn(pszFile, VERR_INVALID_POINTER);
114 AssertPtrReturn(ppszDigest, VERR_INVALID_POINTER);
115 AssertPtrNullReturn(pfnProgressCallback, VERR_INVALID_PARAMETER);
116
117 *ppszDigest = NULL;
118
119 /* Initialize OpenSSL. */
120 SHA256_CTX ctx;
121 if (!SHA256_Init(&ctx))
122 return VERR_INTERNAL_ERROR;
123
124 /* Open the file to calculate a SHA256 sum of */
125 RTFILE hFile;
126 int rc = RTFileOpen(&hFile, pszFile, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
127 if (RT_FAILURE(rc))
128 return rc;
129
130 /* Fetch the file size. Only needed if there is a progress callback. */
131 double rdMulti = 0;
132 if (pfnProgressCallback)
133 {
134 uint64_t cbFile;
135 rc = RTFileGetSize(hFile, &cbFile);
136 if (RT_FAILURE(rc))
137 {
138 RTFileClose(hFile);
139 return rc;
140 }
141 rdMulti = 100.0 / cbFile;
142 }
143
144 /* Allocate a reasonably large buffer, fall back on a tiny one. */
145 void *pvBufFree;
146 size_t cbBuf = _1M;
147 void *pvBuf = pvBufFree = RTMemTmpAlloc(cbBuf);
148 if (!pvBuf)
149 {
150 cbBuf = 0x1000;
151 pvBuf = alloca(cbBuf);
152 }
153
154 /* Read that file in blocks */
155 size_t cbRead;
156 size_t cbReadTotal = 0;
157 for (;;)
158 {
159 rc = RTFileRead(hFile, pvBuf, cbBuf, &cbRead);
160 if (RT_FAILURE(rc) || !cbRead)
161 break;
162 if(!SHA256_Update(&ctx, pvBuf, cbRead))
163 {
164 rc = VERR_INTERNAL_ERROR;
165 break;
166 }
167 cbReadTotal += cbRead;
168
169 /* Call the progress callback if one is defined */
170 if (pfnProgressCallback)
171 {
172 rc = pfnProgressCallback((unsigned)(cbReadTotal * rdMulti), pvUser);
173 if (RT_FAILURE(rc))
174 break; /* canceled */
175 }
176 }
177 RTMemTmpFree(pvBufFree);
178 RTFileClose(hFile);
179
180 if (RT_FAILURE(rc))
181 return rc;
182
183 /* Finally calculate & format the SHA256 sum */
184 unsigned char auchDig[RTSHA256_HASH_SIZE];
185 if (!SHA256_Final(auchDig, &ctx))
186 return VERR_INTERNAL_ERROR;
187
188 char *pszDigest;
189 rc = RTStrAllocEx(&pszDigest, RTSHA256_DIGEST_LEN + 1);
190 if (RT_SUCCESS(rc))
191 {
192 rc = RTSha256ToString(auchDig, pszDigest, RTSHA256_DIGEST_LEN + 1);
193 if (RT_SUCCESS(rc))
194 *ppszDigest = pszDigest;
195 else
196 RTStrFree(pszDigest);
197 }
198
199 return rc;
200}
201
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