7#include "core/fpdfapi/parser/cpdf_crypto_handler.h"
15#include "constants/form_fields.h"
16#include "core/fdrm/fx_crypt.h"
17#include "core/fpdfapi/parser/cpdf_dictionary.h"
18#include "core/fpdfapi/parser/cpdf_number.h"
19#include "core/fpdfapi/parser/cpdf_object_walker.h"
20#include "core/fpdfapi/parser/cpdf_parser.h"
21#include "core/fpdfapi/parser/cpdf_security_handler.h"
22#include "core/fpdfapi/parser/cpdf_simple_parser.h"
23#include "core/fpdfapi/parser/cpdf_stream.h"
24#include "core/fpdfapi/parser/cpdf_stream_acc.h"
25#include "core/fpdfapi/parser/cpdf_string.h"
26#include "core/fxcrt/check.h"
27#include "core/fxcrt/check_op.h"
28#include "core/fxcrt/fx_memcpy_wrappers.h"
29#include "core/fxcrt/stl_util.h"
33constexpr char kContentsKey[] =
"Contents";
34constexpr char kTypeKey[] =
"Type";
44 dictionary->GetDirectObjectFor(kTypeKey);
53 pdfium::span<
const uint8_t> source)
const {
55 return DataVector<uint8_t>(source.begin(), source.end());
58 size_t realkeylen =
sizeof(realkey);
59 if (m_Cipher != Cipher::kAES || m_KeyLen != 32) {
61 PopulateKey(objnum, gennum, key1);
63 fxcrt::Copy(ByteStringView(
"sAlT").unsigned_span(),
64 pdfium::make_span(key1).subspan(m_KeyLen + 5));
66 size_t len = m_Cipher == Cipher::kAES ? m_KeyLen + 9 : m_KeyLen + 5;
67 CRYPT_MD5Generate(
pdfium::make_span(key1).first(len), realkey);
68 realkeylen = std::min(m_KeyLen + 5,
sizeof(realkey));
71 CRYPT_AESSetKey(m_pAESContext.get(),
72 m_KeyLen == 32 ? m_EncryptKey.data() : realkey, m_KeyLen);
74 constexpr size_t kIVSize = 16;
75 constexpr size_t kPaddingSize = 16;
76 const size_t source_padding_size = source.size() % kPaddingSize;
77 const size_t source_data_size = source.size() - source_padding_size;
79 DataVector<uint8_t> dest(kIVSize + source_data_size + kPaddingSize);
80 auto dest_span = pdfium::make_span(dest);
81 auto dest_iv_span = dest_span.first(kIVSize);
82 auto dest_data_span = dest_span.subspan(kIVSize, source_data_size);
83 auto dest_padding_span = dest_span.subspan(kIVSize + source_data_size);
85 for (
auto& v : dest_iv_span) {
86 v =
static_cast<uint8_t>(rand());
88 CRYPT_AESSetIV(m_pAESContext.get(), dest_iv_span.data());
90 CRYPT_AESEncrypt(m_pAESContext.get(), dest_data_span,
91 source.first(source_data_size));
93 std::array<uint8_t, kPaddingSize> padding;
94 fxcrt::Copy(source.subspan(source_data_size, source_padding_size), padding);
95 fxcrt::Fill(
pdfium::make_span(padding).subspan(source_padding_size),
96 16 - source_padding_size);
97 CRYPT_AESEncrypt(m_pAESContext.get(), dest_padding_span, padding);
100 DataVector<uint8_t> dest(source.begin(), source.end());
101 CRYPT_ArcFourCryptBlock(dest, pdfium::make_span(realkey).first(realkeylen));
116 if (m_Cipher == Cipher::kAES && m_KeyLen == 32) {
120 CRYPT_AESSetKey(&pContext->m_Context, m_EncryptKey.data(), 32);
124 PopulateKey(objnum, gennum, key1);
127 UNSAFE_TODO(FXSYS_memcpy(key1 + m_KeyLen + 5,
"sAlT", 4));
131 size_t len = m_Cipher == Cipher::kAES ? m_KeyLen + 9 : m_KeyLen + 5;
132 CRYPT_MD5Generate(
pdfium::make_span(key1).first(len), realkey);
133 size_t realkeylen = std::min(m_KeyLen + 5,
sizeof(realkey));
139 CRYPT_AESSetKey(&pContext->m_Context, realkey, 16);
143 CRYPT_ArcFourSetup(pContext,
pdfium::make_span(realkey).first(realkeylen));
148 pdfium::span<
const uint8_t> source,
154 dest_buf.AppendSpan(source);
158 size_t old_size = dest_buf.GetSize();
159 dest_buf.AppendSpan(source);
162 dest_buf.GetMutableSpan().subspan(old_size, source.size()));
166 uint32_t src_off = 0;
167 uint32_t src_left = source.size();
170 if (copy_size > src_left) {
171 copy_size = src_left;
174 source.data() + src_off, copy_size));
175 src_off += copy_size;
176 src_left -= copy_size;
180 CRYPT_AESSetIV(&pContext->m_Context, pContext
->m_Block);
183 }
else if (src_off < source.size()) {
184 uint8_t block_buf[16];
185 CRYPT_AESDecrypt(&pContext->m_Context, block_buf, pContext
->m_Block,
187 dest_buf.AppendSpan(block_buf);
211 uint8_t block_buf[16];
212 CRYPT_AESDecrypt(&pContext->m_Context, block_buf, pContext
->m_Block, 16);
213 if (block_buf[15] < 16) {
215 pdfium::make_span(block_buf).first(16 - block_buf[15]));
226 void* context = DecryptStart(objnum, gennum);
227 DecryptStream(context, str.unsigned_span(), dest_buf);
228 DecryptFinish(context, dest_buf);
233 return m_Cipher ==
Cipher::kAES ? src_size - 16 : src_size;
244 struct MayBeSignature {
249 std::stack<MayBeSignature> may_be_sign_dictionaries;
250 const uint32_t obj_num = object->GetObjNum();
251 const uint32_t gen_num = object->GetGenNum();
254 while (object_to_decrypt) {
255 CPDF_NonConstObjectWalker walker(
std::move(object_to_decrypt));
256 while (RetainPtr<CPDF_Object> child = walker.GetNext()) {
258 walker.GetParent() ? walker.GetParent()->GetDict() :
nullptr;
260 (parent_dict->KeyExist(kTypeKey) ||
268 may_be_sign_dictionaries.push(
269 {
std::move(parent_dict),
std::move(child)});
274 if (child->IsString()) {
276 CPDF_String* str = child->AsMutableString();
280 if (child->IsStream()) {
282 CPDF_Stream* stream = child->AsMutableStream();
284 pdfium::MakeRetain<CPDF_StreamAcc>(
pdfium::WrapRetain(stream));
285 stream_access->LoadAllDataRaw();
293 decrypted_buf.EstimateSize(DecryptGetSize(stream_access->GetSize()));
295 void* context = DecryptStart(obj_num, gen_num);
296 bool decrypt_result =
297 DecryptStream(context, stream_access->GetSpan(), decrypted_buf);
298 decrypt_result &= DecryptFinish(context, decrypted_buf);
299 if (decrypt_result) {
300 stream->TakeData(decrypted_buf.DetachBuffer());
308 while (!may_be_sign_dictionaries.empty()) {
309 auto dict_and_contents = may_be_sign_dictionaries.top();
310 may_be_sign_dictionaries.pop();
313 object_to_decrypt = dict_and_contents.contents;
322 pdfium::span<
const uint8_t> key)
324 DCHECK(cipher != Cipher::kAES || key.size() == 16 || key.size() == 24 ||
326 DCHECK(cipher != Cipher::kAES2 || key.size() == 32);
327 DCHECK(cipher != Cipher::kRC4 || (key.size() >= 5 && key.size() <= 16));
330 fxcrt::Copy(key.first(m_KeyLen), m_EncryptKey);
333 m_pAESContext.reset(FX_Alloc(CRYPT_aes_context, 1));
341 uint8_t* key)
const {
343 FXSYS_memcpy(key, m_EncryptKey.data(), m_KeyLen);
344 key[m_KeyLen + 0] = (uint8_t)objnum;
345 key[m_KeyLen + 1] = (uint8_t)(objnum >> 8);
346 key[m_KeyLen + 2] = (uint8_t)(objnum >> 16);
347 key[m_KeyLen + 3] = (uint8_t)gennum;
348 key[m_KeyLen + 4] = (uint8_t)(gennum >> 8);
fxcrt::ByteString ByteString
CPDF_CryptoHandler(Cipher cipher, pdfium::span< const uint8_t > key)
bool DecryptObjectTree(RetainPtr< CPDF_Object > object)
static bool IsSignatureDictionary(const CPDF_Dictionary *dictionary)
DataVector< uint8_t > EncryptContent(uint32_t objnum, uint32_t gennum, pdfium::span< const uint8_t > source) const
RetainPtr< const CPDF_Object > GetDirectObjectFor(const ByteString &key) const
std::map< ByteString, RetainPtr< CPDF_Object >, std::less<> > DictMap
void SkipWalkIntoCurrentObject()
const ByteString & dictionary_key() const
void SetString(const ByteString &str) override
ByteString GetString() const override
fxcrt::ByteStringView ByteStringView
CRYPT_aes_context m_Context