CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword( const uint8_t* owner_pass, FX_DWORD pass_size, int32_t key_len) { CFX_ByteString okey = m_pEncryptDict->GetString(FX_BSTRC("O")); uint8_t passcode[32]; FX_DWORD i; for (i = 0; i < 32; i++) { passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size]; } uint8_t digest[16]; CRYPT_MD5Generate(passcode, 32, digest); if (m_Revision >= 3) { for (int i = 0; i < 50; i++) { CRYPT_MD5Generate(digest, 16, digest); } } uint8_t enckey[32]; FXSYS_memset(enckey, 0, sizeof(enckey)); FX_DWORD copy_len = key_len; if (copy_len > sizeof(digest)) { copy_len = sizeof(digest); } FXSYS_memcpy(enckey, digest, copy_len); int okeylen = okey.GetLength(); if (okeylen > 32) { okeylen = 32; } uint8_t okeybuf[64]; FXSYS_memset(okeybuf, 0, sizeof(okeybuf)); FXSYS_memcpy(okeybuf, okey.c_str(), okeylen); if (m_Revision == 2) { CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len); } else { for (int i = 19; i >= 0; i--) { uint8_t tempkey[32]; FXSYS_memset(tempkey, 0, sizeof(tempkey)); for (int j = 0; j < m_KeyLen; j++) { tempkey[j] = enckey[j] ^ i; } CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len); } } int len = 32; while (len && defpasscode[len - 1] == okeybuf[len - 1]) { len--; } return CFX_ByteString(okeybuf, len); }
FX_BOOL CPDF_StandardSecurityHandler::CheckUserPassword( const uint8_t* password, FX_DWORD pass_size, FX_BOOL bIgnoreEncryptMeta, uint8_t* key, int32_t key_len) { CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len, bIgnoreEncryptMeta, m_pParser->GetIDArray()); CFX_ByteString ukey = m_pEncryptDict ? m_pEncryptDict->GetString(FX_BSTRC("U")) : CFX_ByteString(); if (ukey.GetLength() < 16) { return FALSE; } uint8_t ukeybuf[32]; if (m_Revision == 2) { FXSYS_memcpy(ukeybuf, defpasscode, 32); CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len); } else { uint8_t test[32], tmpkey[32]; FX_DWORD copy_len = sizeof(test); if (copy_len > (FX_DWORD)ukey.GetLength()) { copy_len = ukey.GetLength(); } FXSYS_memset(test, 0, sizeof(test)); FXSYS_memset(tmpkey, 0, sizeof(tmpkey)); FXSYS_memcpy(test, ukey.c_str(), copy_len); for (int i = 19; i >= 0; i--) { for (int j = 0; j < key_len; j++) { tmpkey[j] = key[j] ^ i; } CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len); } uint8_t md5[100]; CRYPT_MD5Start(md5); CRYPT_MD5Update(md5, defpasscode, 32); CPDF_Array* pIdArray = m_pParser->GetIDArray(); if (pIdArray) { CFX_ByteString id = pIdArray->GetString(0); CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); } CRYPT_MD5Finish(md5, ukeybuf); return FXSYS_memcmp(test, ukeybuf, 16) == 0; } if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) { return TRUE; } return FALSE; }
void CJS_GlobalData::SaveGlobalPersisitentVariables() { uint32_t nCount = 0; CFX_BinaryBuf sData; for (const auto& pElement : m_arrayGlobalData) { if (pElement->bPersistent) { CFX_BinaryBuf sElement; MakeByteString(pElement->data.sKey, &pElement->data, sElement); if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA) break; sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize()); nCount++; } } CFX_BinaryBuf sFile; uint16_t wType = (uint16_t)(('X' << 8) | 'F'); sFile.AppendBlock(&wType, sizeof(uint16_t)); uint16_t wVersion = 2; sFile.AppendBlock(&wVersion, sizeof(uint16_t)); sFile.AppendBlock(&nCount, sizeof(uint32_t)); uint32_t dwSize = sData.GetSize(); sFile.AppendBlock(&dwSize, sizeof(uint32_t)); sFile.AppendBlock(sData.GetBuffer(), sData.GetSize()); CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY, sizeof(JS_RC4KEY)); WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(), sFile.GetSize()); }
void CPDF_CryptoHandler::CryptBlock(bool bEncrypt, uint32_t objnum, uint32_t gennum, const uint8_t* src_buf, uint32_t src_size, uint8_t* dest_buf, uint32_t& dest_size) { if (m_Cipher == FXCIPHER_NONE) { FXSYS_memcpy(dest_buf, src_buf, src_size); return; } uint8_t realkey[16]; int realkeylen = 16; if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) { uint8_t key1[32]; PopulateKey(objnum, gennum, key1); if (m_Cipher == FXCIPHER_AES) { FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4); } CRYPT_MD5Generate( key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); realkeylen = m_KeyLen + 5; if (realkeylen > 16) { realkeylen = 16; } } if (m_Cipher == FXCIPHER_AES) { CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey, m_KeyLen, bEncrypt); if (bEncrypt) { uint8_t iv[16]; for (int i = 0; i < 16; i++) { iv[i] = (uint8_t)rand(); } CRYPT_AESSetIV(m_pAESContext, iv); FXSYS_memcpy(dest_buf, iv, 16); int nblocks = src_size / 16; CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16); uint8_t padding[16]; FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16); FXSYS_memset(padding + src_size % 16, 16 - src_size % 16, 16 - src_size % 16); CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding, 16); dest_size = 32 + nblocks * 16; } else { CRYPT_AESSetIV(m_pAESContext, src_buf); CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16); dest_size = src_size - 16; dest_size -= dest_buf[dest_size - 1]; } } else { ASSERT(dest_size == src_size); if (dest_buf != src_buf) { FXSYS_memcpy(dest_buf, src_buf, src_size); } CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen); } }
void CJS_GlobalData::SaveGlobalPersisitentVariables() { FX_DWORD nCount = 0; CFX_BinaryBuf sData; for (int i = 0, sz = m_arrayGlobalData.GetSize(); i < sz; i++) { CJS_GlobalData_Element* pElement = m_arrayGlobalData.GetAt(i); if (pElement->bPersistent) { CFX_BinaryBuf sElement; MakeByteString(pElement->data.sKey, &pElement->data, sElement); if (sData.GetSize() + sElement.GetSize() > JS_MAXGLOBALDATA) break; sData.AppendBlock(sElement.GetBuffer(), sElement.GetSize()); nCount++; } } CFX_BinaryBuf sFile; FX_WORD wType = (FX_WORD)(('X' << 8) | 'F'); sFile.AppendBlock(&wType, sizeof(FX_WORD)); FX_WORD wVersion = 2; sFile.AppendBlock(&wVersion, sizeof(FX_WORD)); sFile.AppendBlock(&nCount, sizeof(FX_DWORD)); FX_DWORD dwSize = sData.GetSize(); sFile.AppendBlock(&dwSize, sizeof(FX_DWORD)); sFile.AppendBlock(sData.GetBuffer(), sData.GetSize()); CRYPT_ArcFourCryptBlock(sFile.GetBuffer(), sFile.GetSize(), JS_RC4KEY, sizeof(JS_RC4KEY)); WriteFileBuffer(m_sFilePath.c_str(), (const FX_CHAR*)sFile.GetBuffer(), sFile.GetSize()); }
void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, const uint8_t* user_pass, uint32_t user_size, const uint8_t* owner_pass, uint32_t owner_size, FX_BOOL bDefault, uint32_t type) { int cipher = 0, key_len = 0; if (!LoadDict(pEncryptDict, type, cipher, key_len)) { return; } if (bDefault && (!owner_pass || owner_size == 0)) { owner_pass = user_pass; owner_size = user_size; } if (m_Revision >= 5) { int t = (int)time(nullptr); uint8_t sha[128]; CRYPT_SHA256Start(sha); CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); CRYPT_SHA256Update(sha, m_EncryptKey, 32); CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); CRYPT_SHA256Finish(sha, m_EncryptKey); AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey); if (bDefault) { AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE, m_EncryptKey); AES256_SetPerms(pEncryptDict, m_Permissions, pEncryptDict->GetBooleanBy("EncryptMetadata", true), m_EncryptKey); } return; } if (bDefault) { uint8_t passcode[32]; for (uint32_t i = 0; i < 32; i++) { passcode[i] = i < owner_size ? owner_pass[i] : defpasscode[i - owner_size]; } uint8_t digest[16]; CRYPT_MD5Generate(passcode, 32, digest); if (m_Revision >= 3) { for (uint32_t i = 0; i < 50; i++) CRYPT_MD5Generate(digest, 16, digest); } uint8_t enckey[32]; FXSYS_memcpy(enckey, digest, key_len); for (uint32_t i = 0; i < 32; i++) { passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size]; } CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); uint8_t tempkey[32]; if (m_Revision >= 3) { for (uint8_t i = 1; i <= 19; i++) { for (int j = 0; j < key_len; j++) tempkey[j] = enckey[j] ^ i; CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); } } pEncryptDict->SetAtString("O", CFX_ByteString(passcode, 32)); } CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, key_len, FALSE, pIdArray); if (m_Revision < 3) { uint8_t tempbuf[32]; FXSYS_memcpy(tempbuf, defpasscode, 32); CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); pEncryptDict->SetAtString("U", CFX_ByteString(tempbuf, 32)); } else { uint8_t md5[100]; CRYPT_MD5Start(md5); CRYPT_MD5Update(md5, defpasscode, 32); if (pIdArray) { CFX_ByteString id = pIdArray->GetStringAt(0); CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); } uint8_t digest[32]; CRYPT_MD5Finish(md5, digest); CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); uint8_t tempkey[32]; for (uint8_t i = 1; i <= 19; i++) { for (int j = 0; j < key_len; j++) { tempkey[j] = m_EncryptKey[j] ^ i; } CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); } CRYPT_MD5Generate(digest, 16, digest + 16); pEncryptDict->SetAtString("U", CFX_ByteString(digest, 32)); } }
void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, FX_LPCBYTE user_pass, FX_DWORD user_size, FX_LPCBYTE owner_pass, FX_DWORD owner_size, FX_BOOL bDefault, FX_DWORD type) { int cipher = 0, key_len = 0; if (!LoadDict(pEncryptDict, type, cipher, key_len)) { return; } if (bDefault && (owner_pass == NULL || owner_size == 0)) { owner_pass = user_pass; owner_size = user_size; } if (m_Revision >= 5) { int t = (int)time(NULL); FX_BYTE sha[128]; CRYPT_SHA256Start(sha); CRYPT_SHA256Update(sha, (FX_BYTE*)&t, sizeof t); CRYPT_SHA256Update(sha, m_EncryptKey, 32); CRYPT_SHA256Update(sha, (FX_BYTE*)"there", 5); CRYPT_SHA256Finish(sha, m_EncryptKey); AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey); if (bDefault) { AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE, m_EncryptKey); AES256_SetPerms(pEncryptDict, m_Permissions, pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE), m_EncryptKey); } return; } if (bDefault) { FX_BYTE passcode[32]; FX_DWORD i; for (i = 0; i < 32; i ++) { passcode[i] = i < owner_size ? owner_pass[i] : defpasscode[i - owner_size]; } FX_BYTE digest[16]; CRYPT_MD5Generate(passcode, 32, digest); if (m_Revision >= 3) { for (int i = 0; i < 50; i ++) { CRYPT_MD5Generate(digest, 16, digest); } } FX_BYTE enckey[32]; FXSYS_memcpy32(enckey, digest, key_len); for (i = 0; i < 32; i ++) { passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size]; } CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); FX_BYTE tempkey[32]; if (m_Revision >= 3) { for (i = 1; i <= 19; i ++) { for (int j = 0; j < key_len; j ++) { tempkey[j] = enckey[j] ^ (FX_BYTE)i; } CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); } } pEncryptDict->SetAtString(FX_BSTRC("O"), CFX_ByteString(passcode, 32)); } CalcEncryptKey(m_pEncryptDict, (FX_LPBYTE)user_pass, user_size, m_EncryptKey, key_len, FALSE, pIdArray); if (m_Revision < 3) { FX_BYTE tempbuf[32]; FXSYS_memcpy32(tempbuf, defpasscode, 32); CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(tempbuf, 32)); } else { FX_BYTE md5[100]; CRYPT_MD5Start(md5); CRYPT_MD5Update(md5, defpasscode, 32); if (pIdArray) { CFX_ByteString id = pIdArray->GetString(0); CRYPT_MD5Update(md5, (FX_LPBYTE)(FX_LPCSTR)id, id.GetLength()); } FX_BYTE digest[32]; CRYPT_MD5Finish(md5, digest); CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); FX_BYTE tempkey[32]; for (int i = 1; i <= 19; i ++) { for (int j = 0; j < key_len; j ++) { tempkey[j] = m_EncryptKey[j] ^ (FX_BYTE)i; } CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); } CRYPT_MD5Generate(digest, 16, digest + 16); pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(digest, 32)); } }
void CJS_GlobalData::LoadGlobalPersistentVariables() { uint8_t* pBuffer = nullptr; int32_t nLength = 0; LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength); CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY)); if (pBuffer) { uint8_t* p = pBuffer; uint16_t wType = *((uint16_t*)p); p += sizeof(uint16_t); if (wType == (uint16_t)(('X' << 8) | 'F')) { uint16_t wVersion = *((uint16_t*)p); p += sizeof(uint16_t); ASSERT(wVersion <= 2); uint32_t dwCount = *((uint32_t*)p); p += sizeof(uint32_t); uint32_t dwSize = *((uint32_t*)p); p += sizeof(uint32_t); if (dwSize == nLength - sizeof(uint16_t) * 2 - sizeof(uint32_t) * 2) { for (int32_t i = 0, sz = dwCount; i < sz; i++) { if (p > pBuffer + nLength) break; uint32_t dwNameLen = *((uint32_t*)p); p += sizeof(uint32_t); if (p + dwNameLen > pBuffer + nLength) break; CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen); p += sizeof(char) * dwNameLen; JS_GlobalDataType wDataType = static_cast<JS_GlobalDataType>(*((uint16_t*)p)); p += sizeof(uint16_t); switch (wDataType) { case JS_GlobalDataType::NUMBER: { double dData = 0; switch (wVersion) { case 1: { uint32_t dwData = *((uint32_t*)p); p += sizeof(uint32_t); dData = dwData; } break; case 2: { dData = *((double*)p); p += sizeof(double); } break; } SetGlobalVariableNumber(sEntry, dData); SetGlobalVariablePersistent(sEntry, true); } break; case JS_GlobalDataType::BOOLEAN: { uint16_t wData = *((uint16_t*)p); p += sizeof(uint16_t); SetGlobalVariableBoolean(sEntry, (bool)(wData == 1)); SetGlobalVariablePersistent(sEntry, true); } break; case JS_GlobalDataType::STRING: { uint32_t dwLength = *((uint32_t*)p); p += sizeof(uint32_t); if (p + dwLength > pBuffer + nLength) break; SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength)); SetGlobalVariablePersistent(sEntry, true); p += sizeof(char) * dwLength; } break; case JS_GlobalDataType::NULLOBJ: { SetGlobalVariableNull(sEntry); SetGlobalVariablePersistent(sEntry, true); } case JS_GlobalDataType::OBJECT: break; } } } } FX_Free(pBuffer); } }
void CJS_GlobalData::LoadGlobalPersistentVariables() { uint8_t* pBuffer = NULL; int32_t nLength = 0; LoadFileBuffer(m_sFilePath.c_str(), pBuffer, nLength); CRYPT_ArcFourCryptBlock(pBuffer, nLength, JS_RC4KEY, sizeof(JS_RC4KEY)); if (pBuffer) { uint8_t* p = pBuffer; FX_WORD wType = *((FX_WORD*)p); p += sizeof(FX_WORD); // FX_WORD wTemp = (FX_WORD)(('X' << 8) | 'F'); if (wType == (FX_WORD)(('X' << 8) | 'F')) { FX_WORD wVersion = *((FX_WORD*)p); p += sizeof(FX_WORD); ASSERT(wVersion <= 2); FX_DWORD dwCount = *((FX_DWORD*)p); p += sizeof(FX_DWORD); FX_DWORD dwSize = *((FX_DWORD*)p); p += sizeof(FX_DWORD); if (dwSize == nLength - sizeof(FX_WORD) * 2 - sizeof(FX_DWORD) * 2) { for (int32_t i = 0, sz = dwCount; i < sz; i++) { if (p > pBuffer + nLength) break; FX_DWORD dwNameLen = *((FX_DWORD*)p); p += sizeof(FX_DWORD); if (p + dwNameLen > pBuffer + nLength) break; CFX_ByteString sEntry = CFX_ByteString(p, dwNameLen); p += sizeof(char) * dwNameLen; FX_WORD wDataType = *((FX_WORD*)p); p += sizeof(FX_WORD); switch (wDataType) { case JS_GLOBALDATA_TYPE_NUMBER: { double dData = 0; switch (wVersion) { case 1: { FX_DWORD dwData = *((FX_DWORD*)p); p += sizeof(FX_DWORD); dData = dwData; } break; case 2: { dData = *((double*)p); p += sizeof(double); } break; } SetGlobalVariableNumber(sEntry, dData); SetGlobalVariablePersistent(sEntry, TRUE); } break; case JS_GLOBALDATA_TYPE_BOOLEAN: { FX_WORD wData = *((FX_WORD*)p); p += sizeof(FX_WORD); SetGlobalVariableBoolean(sEntry, (bool)(wData == 1)); SetGlobalVariablePersistent(sEntry, TRUE); } break; case JS_GLOBALDATA_TYPE_STRING: { FX_DWORD dwLength = *((FX_DWORD*)p); p += sizeof(FX_DWORD); if (p + dwLength > pBuffer + nLength) break; SetGlobalVariableString(sEntry, CFX_ByteString(p, dwLength)); SetGlobalVariablePersistent(sEntry, TRUE); p += sizeof(char) * dwLength; } break; case JS_GLOBALDATA_TYPE_NULL: { SetGlobalVariableNull(sEntry); SetGlobalVariablePersistent(sEntry, TRUE); } } } } } FX_Free(pBuffer); } }