Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_encrypt.cpp

Issue 1781593003: Split off IPDF_SecurityHandler and CPDF_StandardSecurityHandler. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Nits Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp ('k') | pdfium.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include "core/include/fpdfapi/fpdf_parser.h" 7 #include "core/include/fpdfapi/fpdf_parser.h"
8 8
9 #include <time.h> 9 #include <time.h>
10 10
11 #include "core/include/fpdfapi/cpdf_parser.h" 11 #include "core/include/fpdfapi/cpdf_parser.h"
12 #include "core/include/fpdfapi/cpdf_simple_parser.h" 12 #include "core/include/fpdfapi/cpdf_simple_parser.h"
13 #include "core/include/fpdfapi/ipdf_security_handler.h"
13 #include "core/include/fdrm/fx_crypt.h" 14 #include "core/include/fdrm/fx_crypt.h"
14 15
15 const uint8_t defpasscode[32] = {
16 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e,
17 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68,
18 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a};
19 void CalcEncryptKey(CPDF_Dictionary* pEncrypt,
20 const uint8_t* password,
21 FX_DWORD pass_size,
22 uint8_t* key,
23 int keylen,
24 FX_BOOL bIgnoreMeta,
25 CPDF_Array* pIdArray) {
26 int revision = pEncrypt->GetIntegerBy("R");
27 uint8_t passcode[32];
28 for (FX_DWORD i = 0; i < 32; i++) {
29 passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size];
30 }
31 uint8_t md5[100];
32 CRYPT_MD5Start(md5);
33 CRYPT_MD5Update(md5, passcode, 32);
34 CFX_ByteString okey = pEncrypt->GetStringBy("O");
35 CRYPT_MD5Update(md5, (uint8_t*)okey.c_str(), okey.GetLength());
36 FX_DWORD perm = pEncrypt->GetIntegerBy("P");
37 CRYPT_MD5Update(md5, (uint8_t*)&perm, 4);
38 if (pIdArray) {
39 CFX_ByteString id = pIdArray->GetStringAt(0);
40 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
41 }
42 if (!bIgnoreMeta && revision >= 3 &&
43 !pEncrypt->GetIntegerBy("EncryptMetadata", 1)) {
44 FX_DWORD tag = (FX_DWORD)-1;
45 CRYPT_MD5Update(md5, (uint8_t*)&tag, 4);
46 }
47 uint8_t digest[16];
48 CRYPT_MD5Finish(md5, digest);
49 FX_DWORD copy_len = keylen;
50 if (copy_len > sizeof(digest)) {
51 copy_len = sizeof(digest);
52 }
53 if (revision >= 3) {
54 for (int i = 0; i < 50; i++) {
55 CRYPT_MD5Generate(digest, copy_len, digest);
56 }
57 }
58 FXSYS_memset(key, 0, keylen);
59 FXSYS_memcpy(key, digest, copy_len);
60 }
61
62 CPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler() {
63 return new CPDF_StandardCryptoHandler;
64 }
65
66 struct PDF_CRYPTOITEM { 16 struct PDF_CRYPTOITEM {
67 int32_t m_Cipher; 17 int32_t m_Cipher;
68 int32_t m_KeyLen; 18 int32_t m_KeyLen;
69 FX_BOOL m_bChecked; 19 FX_BOOL m_bChecked;
70 CPDF_StandardCryptoHandler* m_pCryptoHandler; 20 CPDF_StandardCryptoHandler* m_pCryptoHandler;
71 }; 21 };
72 22
73 CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler() {
74 m_Version = 0;
75 m_Revision = 0;
76 m_pParser = NULL;
77 m_pEncryptDict = NULL;
78 m_Permissions = 0;
79 m_Cipher = FXCIPHER_NONE;
80 m_KeyLen = 0;
81 }
82
83 CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler() {}
84 FX_BOOL CPDF_StandardSecurityHandler::OnInit(CPDF_Parser* pParser,
85 CPDF_Dictionary* pEncryptDict) {
86 m_pParser = pParser;
87 if (!LoadDict(pEncryptDict)) {
88 return FALSE;
89 }
90 if (m_Cipher == FXCIPHER_NONE) {
91 return TRUE;
92 }
93 return CheckSecurity(m_KeyLen);
94 }
95 FX_BOOL CPDF_StandardSecurityHandler::CheckSecurity(int32_t key_len) {
96 CFX_ByteString password = m_pParser->GetPassword();
97 if (CheckPassword(password, password.GetLength(), TRUE, m_EncryptKey,
98 key_len)) {
99 if (password.IsEmpty()) {
100 if (!CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey,
101 key_len)) {
102 return FALSE;
103 }
104 }
105 return TRUE;
106 }
107 return CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey,
108 key_len);
109 }
110 FX_DWORD CPDF_StandardSecurityHandler::GetPermissions() {
111 return m_Permissions;
112 }
113 static FX_BOOL _LoadCryptInfo(CPDF_Dictionary* pEncryptDict,
114 const CFX_ByteStringC& name,
115 int& cipher,
116 int& keylen) {
117 int Version = pEncryptDict->GetIntegerBy("V");
118 cipher = FXCIPHER_RC4;
119 keylen = 0;
120 if (Version >= 4) {
121 CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDictBy("CF");
122 if (!pCryptFilters) {
123 return FALSE;
124 }
125 if (name == "Identity") {
126 cipher = FXCIPHER_NONE;
127 } else {
128 CPDF_Dictionary* pDefFilter = pCryptFilters->GetDictBy(name);
129 if (!pDefFilter) {
130 return FALSE;
131 }
132 int nKeyBits = 0;
133 if (Version == 4) {
134 nKeyBits = pDefFilter->GetIntegerBy("Length", 0);
135 if (nKeyBits == 0) {
136 nKeyBits = pEncryptDict->GetIntegerBy("Length", 128);
137 }
138 } else {
139 nKeyBits = pEncryptDict->GetIntegerBy("Length", 256);
140 }
141 if (nKeyBits < 40) {
142 nKeyBits *= 8;
143 }
144 keylen = nKeyBits / 8;
145 CFX_ByteString cipher_name = pDefFilter->GetStringBy("CFM");
146 if (cipher_name == "AESV2" || cipher_name == "AESV3") {
147 cipher = FXCIPHER_AES;
148 }
149 }
150 } else {
151 keylen = Version > 1 ? pEncryptDict->GetIntegerBy("Length", 40) / 8 : 5;
152 }
153 if (keylen > 32 || keylen < 0) {
154 return FALSE;
155 }
156 return TRUE;
157 }
158
159 FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) {
160 m_pEncryptDict = pEncryptDict;
161 m_Version = pEncryptDict->GetIntegerBy("V");
162 m_Revision = pEncryptDict->GetIntegerBy("R");
163 m_Permissions = pEncryptDict->GetIntegerBy("P", -1);
164 if (m_Version < 4) {
165 return _LoadCryptInfo(pEncryptDict, CFX_ByteString(), m_Cipher, m_KeyLen);
166 }
167 CFX_ByteString stmf_name = pEncryptDict->GetStringBy("StmF");
168 CFX_ByteString strf_name = pEncryptDict->GetStringBy("StrF");
169 if (stmf_name != strf_name) {
170 return FALSE;
171 }
172 if (!_LoadCryptInfo(pEncryptDict, strf_name, m_Cipher, m_KeyLen)) {
173 return FALSE;
174 }
175 return TRUE;
176 }
177
178 FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict,
179 FX_DWORD type,
180 int& cipher,
181 int& key_len) {
182 m_pEncryptDict = pEncryptDict;
183 m_Version = pEncryptDict->GetIntegerBy("V");
184 m_Revision = pEncryptDict->GetIntegerBy("R");
185 m_Permissions = pEncryptDict->GetIntegerBy("P", -1);
186 CFX_ByteString strf_name, stmf_name;
187 if (m_Version >= 4) {
188 stmf_name = pEncryptDict->GetStringBy("StmF");
189 strf_name = pEncryptDict->GetStringBy("StrF");
190 if (stmf_name != strf_name) {
191 return FALSE;
192 }
193 }
194 if (!_LoadCryptInfo(pEncryptDict, strf_name, cipher, key_len)) {
195 return FALSE;
196 }
197 m_Cipher = cipher;
198 m_KeyLen = key_len;
199 return TRUE;
200 }
201
202 FX_BOOL CPDF_StandardSecurityHandler::GetCryptInfo(int& cipher,
203 const uint8_t*& buffer,
204 int& keylen) {
205 cipher = m_Cipher;
206 buffer = m_EncryptKey;
207 keylen = m_KeyLen;
208 return TRUE;
209 }
210 #define FX_GET_32WORD(n, b, i) \
211 { \
212 (n) = (FX_DWORD)( \
213 ((uint64_t)(b)[(i)] << 24) | ((uint64_t)(b)[(i) + 1] << 16) | \
214 ((uint64_t)(b)[(i) + 2] << 8) | ((uint64_t)(b)[(i) + 3])); \
215 }
216 int BigOrder64BitsMod3(uint8_t* data) {
217 uint64_t ret = 0;
218 for (int i = 0; i < 4; ++i) {
219 FX_DWORD value;
220 FX_GET_32WORD(value, data, 4 * i);
221 ret <<= 32;
222 ret |= value;
223 ret %= 3;
224 }
225 return (int)ret;
226 }
227 void Revision6_Hash(const uint8_t* password,
228 FX_DWORD size,
229 const uint8_t* salt,
230 const uint8_t* vector,
231 uint8_t* hash) {
232 int iBlockSize = 32;
233 uint8_t sha[128];
234 CRYPT_SHA256Start(sha);
235 CRYPT_SHA256Update(sha, password, size);
236 CRYPT_SHA256Update(sha, salt, 8);
237 if (vector) {
238 CRYPT_SHA256Update(sha, vector, 48);
239 }
240 uint8_t digest[32];
241 CRYPT_SHA256Finish(sha, digest);
242 CFX_ByteTextBuf buf;
243 uint8_t* input = digest;
244 uint8_t* key = input;
245 uint8_t* iv = input + 16;
246 uint8_t* E = buf.GetBuffer();
247 int iBufLen = buf.GetLength();
248 CFX_ByteTextBuf interDigest;
249 int i = 0;
250 uint8_t* aes = FX_Alloc(uint8_t, 2048);
251 while (i < 64 || i < E[iBufLen - 1] + 32) {
252 int iRoundSize = size + iBlockSize;
253 if (vector) {
254 iRoundSize += 48;
255 }
256 iBufLen = iRoundSize * 64;
257 buf.EstimateSize(iBufLen);
258 E = buf.GetBuffer();
259 CFX_ByteTextBuf content;
260 for (int j = 0; j < 64; ++j) {
261 content.AppendBlock(password, size);
262 content.AppendBlock(input, iBlockSize);
263 if (vector) {
264 content.AppendBlock(vector, 48);
265 }
266 }
267 CRYPT_AESSetKey(aes, 16, key, 16, TRUE);
268 CRYPT_AESSetIV(aes, iv);
269 CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen);
270 int iHash = 0;
271 switch (BigOrder64BitsMod3(E)) {
272 case 0:
273 iHash = 0;
274 iBlockSize = 32;
275 break;
276 case 1:
277 iHash = 1;
278 iBlockSize = 48;
279 break;
280 default:
281 iHash = 2;
282 iBlockSize = 64;
283 break;
284 }
285 interDigest.EstimateSize(iBlockSize);
286 input = interDigest.GetBuffer();
287 if (iHash == 0) {
288 CRYPT_SHA256Generate(E, iBufLen, input);
289 } else if (iHash == 1) {
290 CRYPT_SHA384Generate(E, iBufLen, input);
291 } else if (iHash == 2) {
292 CRYPT_SHA512Generate(E, iBufLen, input);
293 }
294 key = input;
295 iv = input + 16;
296 ++i;
297 }
298 FX_Free(aes);
299 if (hash) {
300 FXSYS_memcpy(hash, input, 32);
301 }
302 }
303 FX_BOOL CPDF_StandardSecurityHandler::AES256_CheckPassword(
304 const uint8_t* password,
305 FX_DWORD size,
306 FX_BOOL bOwner,
307 uint8_t* key) {
308 CFX_ByteString okey =
309 m_pEncryptDict ? m_pEncryptDict->GetStringBy("O") : CFX_ByteString();
310 if (okey.GetLength() < 48) {
311 return FALSE;
312 }
313 CFX_ByteString ukey =
314 m_pEncryptDict ? m_pEncryptDict->GetStringBy("U") : CFX_ByteString();
315 if (ukey.GetLength() < 48) {
316 return FALSE;
317 }
318 const uint8_t* pkey = bOwner ? (const uint8_t*)okey : (const uint8_t*)ukey;
319 uint8_t sha[128];
320 uint8_t digest[32];
321 if (m_Revision >= 6) {
322 Revision6_Hash(password, size, (const uint8_t*)pkey + 32,
323 (bOwner ? (const uint8_t*)ukey : NULL), digest);
324 } else {
325 CRYPT_SHA256Start(sha);
326 CRYPT_SHA256Update(sha, password, size);
327 CRYPT_SHA256Update(sha, pkey + 32, 8);
328 if (bOwner) {
329 CRYPT_SHA256Update(sha, ukey, 48);
330 }
331 CRYPT_SHA256Finish(sha, digest);
332 }
333 if (FXSYS_memcmp(digest, pkey, 32) != 0) {
334 return FALSE;
335 }
336 if (!key) {
337 return TRUE;
338 }
339 if (m_Revision >= 6) {
340 Revision6_Hash(password, size, (const uint8_t*)pkey + 40,
341 (bOwner ? (const uint8_t*)ukey : NULL), digest);
342 } else {
343 CRYPT_SHA256Start(sha);
344 CRYPT_SHA256Update(sha, password, size);
345 CRYPT_SHA256Update(sha, pkey + 40, 8);
346 if (bOwner) {
347 CRYPT_SHA256Update(sha, ukey, 48);
348 }
349 CRYPT_SHA256Finish(sha, digest);
350 }
351 CFX_ByteString ekey = m_pEncryptDict
352 ? m_pEncryptDict->GetStringBy(bOwner ? "OE" : "UE")
353 : CFX_ByteString();
354 if (ekey.GetLength() < 32) {
355 return FALSE;
356 }
357 uint8_t* aes = FX_Alloc(uint8_t, 2048);
358 CRYPT_AESSetKey(aes, 16, digest, 32, FALSE);
359 uint8_t iv[16];
360 FXSYS_memset(iv, 0, 16);
361 CRYPT_AESSetIV(aes, iv);
362 CRYPT_AESDecrypt(aes, key, ekey, 32);
363 CRYPT_AESSetKey(aes, 16, key, 32, FALSE);
364 CRYPT_AESSetIV(aes, iv);
365 CFX_ByteString perms = m_pEncryptDict->GetStringBy("Perms");
366 if (perms.IsEmpty()) {
367 return FALSE;
368 }
369 uint8_t perms_buf[16];
370 FXSYS_memset(perms_buf, 0, sizeof(perms_buf));
371 FX_DWORD copy_len = sizeof(perms_buf);
372 if (copy_len > (FX_DWORD)perms.GetLength()) {
373 copy_len = perms.GetLength();
374 }
375 FXSYS_memcpy(perms_buf, (const uint8_t*)perms, copy_len);
376 uint8_t buf[16];
377 CRYPT_AESDecrypt(aes, buf, perms_buf, 16);
378 FX_Free(aes);
379 if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') {
380 return FALSE;
381 }
382 if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) {
383 return FALSE;
384 }
385 if ((buf[8] == 'T' && !IsMetadataEncrypted()) ||
386 (buf[8] == 'F' && IsMetadataEncrypted())) {
387 return FALSE;
388 }
389 return TRUE;
390 }
391
392 int CPDF_StandardSecurityHandler::CheckPassword(const uint8_t* password,
393 FX_DWORD size,
394 FX_BOOL bOwner,
395 uint8_t* key,
396 int32_t key_len) {
397 if (m_Revision >= 5) {
398 return AES256_CheckPassword(password, size, bOwner, key);
399 }
400 uint8_t keybuf[32];
401 if (!key) {
402 key = keybuf;
403 }
404 if (bOwner) {
405 return CheckOwnerPassword(password, size, key, key_len);
406 }
407 return CheckUserPassword(password, size, FALSE, key, key_len) ||
408 CheckUserPassword(password, size, TRUE, key, key_len);
409 }
410 FX_BOOL CPDF_StandardSecurityHandler::CheckUserPassword(
411 const uint8_t* password,
412 FX_DWORD pass_size,
413 FX_BOOL bIgnoreEncryptMeta,
414 uint8_t* key,
415 int32_t key_len) {
416 CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len,
417 bIgnoreEncryptMeta, m_pParser->GetIDArray());
418 CFX_ByteString ukey =
419 m_pEncryptDict ? m_pEncryptDict->GetStringBy("U") : CFX_ByteString();
420 if (ukey.GetLength() < 16) {
421 return FALSE;
422 }
423 uint8_t ukeybuf[32];
424 if (m_Revision == 2) {
425 FXSYS_memcpy(ukeybuf, defpasscode, 32);
426 CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len);
427 } else {
428 uint8_t test[32], tmpkey[32];
429 FX_DWORD copy_len = sizeof(test);
430 if (copy_len > (FX_DWORD)ukey.GetLength()) {
431 copy_len = ukey.GetLength();
432 }
433 FXSYS_memset(test, 0, sizeof(test));
434 FXSYS_memset(tmpkey, 0, sizeof(tmpkey));
435 FXSYS_memcpy(test, ukey.c_str(), copy_len);
436 for (int i = 19; i >= 0; i--) {
437 for (int j = 0; j < key_len; j++) {
438 tmpkey[j] = key[j] ^ i;
439 }
440 CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len);
441 }
442 uint8_t md5[100];
443 CRYPT_MD5Start(md5);
444 CRYPT_MD5Update(md5, defpasscode, 32);
445 CPDF_Array* pIdArray = m_pParser->GetIDArray();
446 if (pIdArray) {
447 CFX_ByteString id = pIdArray->GetStringAt(0);
448 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
449 }
450 CRYPT_MD5Finish(md5, ukeybuf);
451 return FXSYS_memcmp(test, ukeybuf, 16) == 0;
452 }
453 if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) {
454 return TRUE;
455 }
456 return FALSE;
457 }
458 CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(
459 const uint8_t* owner_pass,
460 FX_DWORD pass_size,
461 int32_t key_len) {
462 CFX_ByteString okey = m_pEncryptDict->GetStringBy("O");
463 uint8_t passcode[32];
464 FX_DWORD i;
465 for (i = 0; i < 32; i++) {
466 passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size];
467 }
468 uint8_t digest[16];
469 CRYPT_MD5Generate(passcode, 32, digest);
470 if (m_Revision >= 3) {
471 for (int i = 0; i < 50; i++) {
472 CRYPT_MD5Generate(digest, 16, digest);
473 }
474 }
475 uint8_t enckey[32];
476 FXSYS_memset(enckey, 0, sizeof(enckey));
477 FX_DWORD copy_len = key_len;
478 if (copy_len > sizeof(digest)) {
479 copy_len = sizeof(digest);
480 }
481 FXSYS_memcpy(enckey, digest, copy_len);
482 int okeylen = okey.GetLength();
483 if (okeylen > 32) {
484 okeylen = 32;
485 }
486 uint8_t okeybuf[64];
487 FXSYS_memset(okeybuf, 0, sizeof(okeybuf));
488 FXSYS_memcpy(okeybuf, okey.c_str(), okeylen);
489 if (m_Revision == 2) {
490 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len);
491 } else {
492 for (int i = 19; i >= 0; i--) {
493 uint8_t tempkey[32];
494 FXSYS_memset(tempkey, 0, sizeof(tempkey));
495 for (int j = 0; j < m_KeyLen; j++) {
496 tempkey[j] = enckey[j] ^ i;
497 }
498 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len);
499 }
500 }
501 int len = 32;
502 while (len && defpasscode[len - 1] == okeybuf[len - 1]) {
503 len--;
504 }
505 return CFX_ByteString(okeybuf, len);
506 }
507 FX_BOOL CPDF_StandardSecurityHandler::CheckOwnerPassword(
508 const uint8_t* password,
509 FX_DWORD pass_size,
510 uint8_t* key,
511 int32_t key_len) {
512 CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len);
513 if (CheckUserPassword(user_pass, user_pass.GetLength(), FALSE, key,
514 key_len)) {
515 return TRUE;
516 }
517 return CheckUserPassword(user_pass, user_pass.GetLength(), TRUE, key,
518 key_len);
519 }
520 FX_BOOL CPDF_StandardSecurityHandler::IsMetadataEncrypted() {
521 return m_pEncryptDict->GetBooleanBy("EncryptMetadata", TRUE);
522 }
523
524 IPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler() {
525 return new CPDF_StandardSecurityHandler;
526 }
527
528 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
529 CPDF_Array* pIdArray,
530 const uint8_t* user_pass,
531 FX_DWORD user_size,
532 const uint8_t* owner_pass,
533 FX_DWORD owner_size,
534 FX_BOOL bDefault,
535 FX_DWORD type) {
536 int cipher = 0, key_len = 0;
537 if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
538 return;
539 }
540 if (bDefault && (!owner_pass || owner_size == 0)) {
541 owner_pass = user_pass;
542 owner_size = user_size;
543 }
544 if (m_Revision >= 5) {
545 int t = (int)time(NULL);
546 uint8_t sha[128];
547 CRYPT_SHA256Start(sha);
548 CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t);
549 CRYPT_SHA256Update(sha, m_EncryptKey, 32);
550 CRYPT_SHA256Update(sha, (uint8_t*)"there", 5);
551 CRYPT_SHA256Finish(sha, m_EncryptKey);
552 AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey);
553 if (bDefault) {
554 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE,
555 m_EncryptKey);
556 AES256_SetPerms(pEncryptDict, m_Permissions,
557 pEncryptDict->GetBooleanBy("EncryptMetadata", TRUE),
558 m_EncryptKey);
559 }
560 return;
561 }
562 if (bDefault) {
563 uint8_t passcode[32];
564 FX_DWORD i;
565 for (i = 0; i < 32; i++) {
566 passcode[i] =
567 i < owner_size ? owner_pass[i] : defpasscode[i - owner_size];
568 }
569 uint8_t digest[16];
570 CRYPT_MD5Generate(passcode, 32, digest);
571 if (m_Revision >= 3) {
572 for (int i = 0; i < 50; i++) {
573 CRYPT_MD5Generate(digest, 16, digest);
574 }
575 }
576 uint8_t enckey[32];
577 FXSYS_memcpy(enckey, digest, key_len);
578 for (i = 0; i < 32; i++) {
579 passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size];
580 }
581 CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len);
582 uint8_t tempkey[32];
583 if (m_Revision >= 3) {
584 for (i = 1; i <= 19; i++) {
585 for (int j = 0; j < key_len; j++) {
586 tempkey[j] = enckey[j] ^ (uint8_t)i;
587 }
588 CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len);
589 }
590 }
591 pEncryptDict->SetAtString("O", CFX_ByteString(passcode, 32));
592 }
593 CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey,
594 key_len, FALSE, pIdArray);
595 if (m_Revision < 3) {
596 uint8_t tempbuf[32];
597 FXSYS_memcpy(tempbuf, defpasscode, 32);
598 CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len);
599 pEncryptDict->SetAtString("U", CFX_ByteString(tempbuf, 32));
600 } else {
601 uint8_t md5[100];
602 CRYPT_MD5Start(md5);
603 CRYPT_MD5Update(md5, defpasscode, 32);
604 if (pIdArray) {
605 CFX_ByteString id = pIdArray->GetStringAt(0);
606 CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength());
607 }
608 uint8_t digest[32];
609 CRYPT_MD5Finish(md5, digest);
610 CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len);
611 uint8_t tempkey[32];
612 for (int i = 1; i <= 19; i++) {
613 for (int j = 0; j < key_len; j++) {
614 tempkey[j] = m_EncryptKey[j] ^ (uint8_t)i;
615 }
616 CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len);
617 }
618 CRYPT_MD5Generate(digest, 16, digest + 16);
619 pEncryptDict->SetAtString("U", CFX_ByteString(digest, 32));
620 }
621 }
622 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
623 CPDF_Array* pIdArray,
624 const uint8_t* user_pass,
625 FX_DWORD user_size,
626 const uint8_t* owner_pass,
627 FX_DWORD owner_size,
628 FX_DWORD type) {
629 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size,
630 TRUE, type);
631 }
632 void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict,
633 CPDF_Array* pIdArray,
634 const uint8_t* user_pass,
635 FX_DWORD user_size,
636 FX_DWORD type) {
637 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, NULL, 0, FALSE, type);
638 }
639 void CPDF_StandardSecurityHandler::AES256_SetPassword(
640 CPDF_Dictionary* pEncryptDict,
641 const uint8_t* password,
642 FX_DWORD size,
643 FX_BOOL bOwner,
644 const uint8_t* key) {
645 uint8_t sha[128];
646 CRYPT_SHA1Start(sha);
647 CRYPT_SHA1Update(sha, key, 32);
648 CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5);
649 uint8_t digest[20];
650 CRYPT_SHA1Finish(sha, digest);
651 CFX_ByteString ukey = pEncryptDict->GetStringBy("U");
652 uint8_t digest1[48];
653 if (m_Revision >= 6) {
654 Revision6_Hash(password, size, digest,
655 (bOwner ? (const uint8_t*)ukey : NULL), digest1);
656 } else {
657 CRYPT_SHA256Start(sha);
658 CRYPT_SHA256Update(sha, password, size);
659 CRYPT_SHA256Update(sha, digest, 8);
660 if (bOwner) {
661 CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
662 }
663 CRYPT_SHA256Finish(sha, digest1);
664 }
665 FXSYS_memcpy(digest1 + 32, digest, 16);
666 pEncryptDict->SetAtString(bOwner ? "O" : "U", CFX_ByteString(digest1, 48));
667 if (m_Revision >= 6) {
668 Revision6_Hash(password, size, digest + 8,
669 (bOwner ? (const uint8_t*)ukey : NULL), digest1);
670 } else {
671 CRYPT_SHA256Start(sha);
672 CRYPT_SHA256Update(sha, password, size);
673 CRYPT_SHA256Update(sha, digest + 8, 8);
674 if (bOwner) {
675 CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
676 }
677 CRYPT_SHA256Finish(sha, digest1);
678 }
679 uint8_t* aes = FX_Alloc(uint8_t, 2048);
680 CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE);
681 uint8_t iv[16];
682 FXSYS_memset(iv, 0, 16);
683 CRYPT_AESSetIV(aes, iv);
684 CRYPT_AESEncrypt(aes, digest1, key, 32);
685 FX_Free(aes);
686 pEncryptDict->SetAtString(bOwner ? "OE" : "UE", CFX_ByteString(digest1, 32));
687 }
688 void CPDF_StandardSecurityHandler::AES256_SetPerms(
689 CPDF_Dictionary* pEncryptDict,
690 FX_DWORD permissions,
691 FX_BOOL bEncryptMetadata,
692 const uint8_t* key) {
693 uint8_t buf[16];
694 buf[0] = (uint8_t)permissions;
695 buf[1] = (uint8_t)(permissions >> 8);
696 buf[2] = (uint8_t)(permissions >> 16);
697 buf[3] = (uint8_t)(permissions >> 24);
698 buf[4] = 0xff;
699 buf[5] = 0xff;
700 buf[6] = 0xff;
701 buf[7] = 0xff;
702 buf[8] = bEncryptMetadata ? 'T' : 'F';
703 buf[9] = 'a';
704 buf[10] = 'd';
705 buf[11] = 'b';
706 uint8_t* aes = FX_Alloc(uint8_t, 2048);
707 CRYPT_AESSetKey(aes, 16, key, 32, TRUE);
708 uint8_t iv[16], buf1[16];
709 FXSYS_memset(iv, 0, 16);
710 CRYPT_AESSetIV(aes, iv);
711 CRYPT_AESEncrypt(aes, buf1, buf, 16);
712 FX_Free(aes);
713 pEncryptDict->SetAtString("Perms", CFX_ByteString(buf1, 16));
714 }
715 void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt, 23 void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt,
716 FX_DWORD objnum, 24 FX_DWORD objnum,
717 FX_DWORD gennum, 25 FX_DWORD gennum,
718 const uint8_t* src_buf, 26 const uint8_t* src_buf,
719 FX_DWORD src_size, 27 FX_DWORD src_size,
720 uint8_t* dest_buf, 28 uint8_t* dest_buf,
721 FX_DWORD& dest_size) { 29 FX_DWORD& dest_size) {
722 if (m_Cipher == FXCIPHER_NONE) { 30 if (m_Cipher == FXCIPHER_NONE) {
723 FXSYS_memcpy(dest_buf, src_buf, src_size); 31 FXSYS_memcpy(dest_buf, src_buf, src_size);
724 return; 32 return;
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1029 str = dest_buf; 337 str = dest_buf;
1030 } 338 }
1031 CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler() { 339 CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler() {
1032 m_pAESContext = NULL; 340 m_pAESContext = NULL;
1033 m_Cipher = FXCIPHER_NONE; 341 m_Cipher = FXCIPHER_NONE;
1034 m_KeyLen = 0; 342 m_KeyLen = 0;
1035 } 343 }
1036 CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler() { 344 CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler() {
1037 FX_Free(m_pAESContext); 345 FX_Free(m_pAESContext);
1038 } 346 }
OLDNEW
« no previous file with comments | « core/src/fpdfapi/fpdf_parser/cpdf_standard_security_handler.cpp ('k') | pdfium.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698