Develop and Download Open Source Software

Browse CVS Repository

Contents of /tombo/Tombo/Src/CryptManager.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.8 - (show annotations) (download) (as text)
Thu Feb 9 15:52:08 2006 UTC (18 years, 2 months ago) by hirami
Branch: MAIN
CVS Tags: Tombo_2_0a3, Tombo_1_17_1, B201, B202, B203, B205, B206, B207, B208, B213, B212, B211, B217, B216, B215, B214, B219, B218, Tombo_2_0b2, Tombo_2_0b3, Tombo_2_0b1, Tombo_2_0b4, B228, B229, B226, B227, B224, B225, B222, B223, B220, B221, B231, B230, Tombo_1_17, Tombo_1_16, HEAD
Branch point for: Tombo_1_17_1_branch
Changes since 1.7: +3 -2 lines
File MIME type: text/x-c++src
* Fixed memory some leaks about SecureBuffer[TA]. SecureBuffer has replaced to SecureBufferAutoPointer[TA]
* Fix: search position is wrong when search twice or more.(WinCE)
* Save/Load UTF-8/Unicode support(#5814)

1 #include <windows.h>
2 #include <stdlib.h>
3 #include "CryptManager.h"
4 #include "File.h"
5
6 void WipeOutAndDelete(char *p, DWORD len);
7 #ifdef _WIN32_WCE
8 void WipeOutAndDelete(LPTSTR p, DWORD len);
9 #endif
10
11 BOOL CryptManager::Init(const char *pKey)
12 {
13 SYSTEMTIME st;
14 GetSystemTime(&st);
15 FILETIME ft;
16 SystemTimeToFileTime(&st, &ft);
17 srand(ft.dwLowDateTime);
18
19 getMD5Sum(md5key, (byte*)pKey, strlen(pKey));
20 return TRUE;
21 }
22
23 //////////////////////////////////////////////////
24 // デストラクタ
25 //////////////////////////////////////////////////
26 // セキュリティ上、保持していたmd5keyを消去する。
27
28 CryptManager::~CryptManager()
29 {
30 for (DWORD i = 0; i < 16; i++) {
31 md5key[i] = 0;
32 }
33 }
34
35 //////////////////////////////////////////////////
36 // データの暗号化
37 //////////////////////////////////////////////////
38
39 BOOL CryptManager::Encrypt(LPBYTE pBuf, int len)
40 {
41 if (len == 0) return FALSE;
42
43 if (!crypt.ResetStream(md5key, 16)) return FALSE;
44 BYTE buf[8];
45 LPBYTE p = pBuf;
46 int n = len;
47 int i;
48 while (n > 8) {
49 for (i = 0; i < 8; i++) {
50 buf[i] = p[i];
51 }
52 crypt.Encrypt(p, buf, 8);
53 p += 8;
54 n -= 8;
55 }
56 if (n > 0) {
57 for (i = 0; i < n; i++) {
58 buf[i] = p[i];
59 }
60 crypt.Encrypt(p, buf, n);
61 }
62
63 for (i = 0; i < 8; i++) buf[i] = 0;
64 return TRUE;
65 }
66
67 //////////////////////////////////////////////////
68 // データの復号
69 //////////////////////////////////////////////////
70
71 BOOL CryptManager::Decrypt(LPBYTE pBuf, int len)
72 {
73 if (len == 0) return FALSE;
74
75 if (!crypt.ResetStream(md5key, 16)) return FALSE;
76
77 BYTE buf[8];
78 LPBYTE p = pBuf;
79 int n = len;
80 int i;
81 while (n >= 8) {
82 for (i = 0; i < 8; i++) {
83 buf[i] = p[i];
84 }
85 crypt.Decrypt(p, buf);
86 p += 8;
87 n -= 8;
88 }
89
90 for (i = 0; i < 8; i++) buf[i] = 0;
91 return TRUE;
92 }
93
94 //////////////////////////////////////////////////
95 // データの暗号化とファイルへの保存
96 //////////////////////////////////////////////////
97
98 BOOL CryptManager::EncryptAndStore(const LPBYTE pData, int nSize, LPCTSTR pFileName)
99 {
100 int len;
101 LPBYTE pBuf = EncryptBuffer(pData, nSize, &len);
102 // ファイルへの保存
103 File outf;
104
105 if (!outf.Open(pFileName, GENERIC_WRITE, 0, OPEN_ALWAYS)) {
106 WipeOutAndDelete((char*)pBuf, len);
107 return FALSE;
108 }
109 if (!outf.Write(pBuf, len)) {
110 TCHAR buf[1024];
111 wsprintf(buf, TEXT("CryptManager::EncryptAndStore write failed %d"), GetLastError());
112 MessageBox(NULL, buf, TEXT("DEBUG"), MB_OK);
113 }
114 if (!outf.SetEOF()) return FALSE;
115 outf.Close();
116
117 WipeOutAndDelete((char*)pBuf, len);
118 return TRUE;
119 }
120
121 //////////////////////////////////////////////////
122 // Encrypt data and add header
123 //////////////////////////////////////////////////
124 // CryptManagerによる暗号化ファイルのフォーマット
125 // The format of the container is:
126 // 0-3 : BF01(4 bytes)
127 // 4-7 : data length (include randum area + md5sum)(4 bytes)
128 // 8-15 :* random data(8 bytes)
129 //16-31 :* md5sum of plain text(16 bytes)
130 //32- :* data
131
132 // '*' is encrypted.
133 //
134
135 LPBYTE CryptManager::EncryptBuffer(const LPBYTE pData, int nSize, int *pLen)
136 {
137 int i=0;
138 int len = ((nSize >> 3) + 1) * 8;
139 len += 24;
140
141 len += 8;
142
143 LPBYTE pBufF = new BYTE[len];
144 if (pBufF == NULL) {
145 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
146 return NULL;
147 }
148 LPBYTE pBuf = pBufF + 8;
149
150 // set random number
151 for (i = 0; i < 8; i++) {
152 pBuf[i] = (BYTE)(rand() & 0xFF);
153 }
154
155 strncpy((char*)pBufF, "BF01", 4);
156 *(int*)(pBufF + 4) = nSize;
157
158 // get md5sum of plain data
159 getMD5Sum(pBuf + 8, pData, nSize);
160
161 // copy plain data
162 LPBYTE p = pBuf + 24;
163 const BYTE *q = pData;
164 for (i = 0; i < nSize; i++) {
165 *p++ = *q++;
166 }
167
168 // encryption
169 if (!Encrypt(pBuf, nSize + 24)) {
170 WipeOutAndDelete((char*)pBufF, len);
171 return NULL;
172 }
173 *pLen = len;
174 return pBufF;
175 }
176
177 //////////////////////////////////////////////////
178 // Load from file and decrypt data
179 //////////////////////////////////////////////////
180
181 LPBYTE CryptManager::LoadAndDecrypt(LPDWORD pSize, LPCTSTR pFileName)
182 {
183 File inf;
184 if (!inf.Open(pFileName, GENERIC_READ, 0, OPEN_EXISTING)) {
185 return NULL;
186 }
187
188 DWORD nFileSize = inf.FileSize();
189 char version[5];
190 DWORD n;
191 DWORD nDataSize;
192
193 // バージョンヘッダ
194 n = 4;
195 inf.Read((LPBYTE)version, &n);
196 version[4] = '\0';
197 if (strcmp(version, "BF01") != 0) {
198 SetLastError(ERROR_INVALID_DATA);
199 return NULL;
200 }
201
202 // データ長
203 n = sizeof(nDataSize);
204 inf.Read((LPBYTE)&nDataSize, &n);
205
206 LPBYTE pBuf = new BYTE[nFileSize + 1];
207 n = nFileSize - 4 - sizeof(nDataSize);
208 inf.Read(pBuf, &n);
209
210 if (!Decrypt(pBuf, n)) {
211 WipeOutAndDelete((char*)pBuf, nFileSize + 1);
212 return NULL;
213 }
214
215 // 復号化文MD5SUMの取得
216 BYTE decriptsum[16];
217 getMD5Sum(decriptsum, pBuf + 24, nDataSize);
218
219 // 正しく復号化できたかのチェック
220 for (int i = 0; i < 16; i++) {
221 if (pBuf[8 + i] != decriptsum[i]) {
222 WipeOutAndDelete((char*)pBuf, nFileSize + 1);
223 SetLastError(ERROR_INVALID_PASSWORD);
224 return NULL;
225 }
226 }
227 pBuf[nDataSize + 24] = '\0';
228 *pSize = nDataSize;
229
230 // 領域再確保
231 // 乱数データとMD5SUMをまとめて復号化するために1つのバッファで確保したが、
232 // deleteを正しく行えるように領域を再確保、コピーして返す
233 LPBYTE pData = new BYTE[nDataSize + 2];
234 if (pData == NULL) {
235 WipeOutAndDelete((char*)pBuf, nFileSize + 2);
236 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
237 return NULL;
238 }
239 memcpy(pData, pBuf + 24, nDataSize);
240 pData[nDataSize] = '\0';
241 pData[nDataSize + 1] = '\0'; // sentinel for the file is UTF16
242 WipeOutAndDelete((char*)pBuf, nFileSize + 1);
243 return pData;
244 }
245
246 LPBYTE CryptManager::DecryptBuffer(const LPBYTE pCrypted, int nSize)
247 {
248 if (nSize % 8 != 0) {
249 SetLastError(ERROR_INVALID_DATA);
250 return NULL;
251 }
252
253 LPBYTE pBuf = new BYTE[nSize];
254 if (pBuf == NULL) return NULL;
255
256 memcpy(pBuf, pCrypted, nSize);
257
258 if (!Decrypt(pBuf + 8, nSize - 8)) {
259 WipeOutAndDelete((char*)pBuf, nSize);
260 return NULL;
261 }
262
263 DWORD n = *(LPDWORD)(pBuf + 4);
264
265 BYTE decriptsum[16];
266 getMD5Sum(decriptsum, pBuf + 32, n);
267
268 for (int i = 0; i < 16; i++) {
269 if (pBuf[16 + i] != decriptsum[i]) {
270 WipeOutAndDelete((char*)pBuf, nSize);
271 SetLastError(ERROR_INVALID_PASSWORD);
272 return NULL;
273 }
274 }
275
276 LPBYTE pData = new BYTE[n + 1];
277 if (pData == NULL) {
278 WipeOutAndDelete((char*)pBuf, nSize);
279 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
280 return NULL;
281 }
282 memcpy(pData, pBuf + 32, n);
283 pData[n] = 0;
284
285 WipeOutAndDelete((char*)pBuf, nSize);
286 return pData;
287 }
288
289 void WipeOutAndDelete(LPTSTR p, DWORD len)
290 {
291 for (DWORD i = 0; i < len; i++) p[i] = TEXT('\0');
292 delete [] p;
293 }
294
295
296 #ifdef _WIN32_WCE
297 void WipeOutAndDelete(char *p, DWORD len)
298 {
299 for (DWORD i = 0; i < len; i++) p[i] = TEXT('\0');
300 delete [] p;
301 }
302
303 #endif
304

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26